Spaces:
Sleeping
Sleeping
| import pytest | |
| from domains.belief.belief_domain import BeliefUpdate | |
| from domains.coordination.game_coordination import BayesianGame, GamePhase, GameState | |
| from domains.environment.environment_domain import EnvironmentEvidence | |
| class TestGameState: | |
| """Test the GameState dataclass.""" | |
| def test_game_state_creation(self): | |
| """Test creating game state with required parameters.""" | |
| state = GameState(round_number=5, max_rounds=10, phase=GamePhase.PLAYING) | |
| assert state.round_number == 5 | |
| assert state.max_rounds == 10 | |
| assert state.phase == GamePhase.PLAYING | |
| assert state.target_value is None | |
| assert state.evidence_history == [] | |
| assert state.current_beliefs == [] | |
| def test_game_state_with_optional_params(self): | |
| """Test creating game state with optional parameters.""" | |
| evidence = [EnvironmentEvidence(dice_roll=3, comparison_results=["higher"])] | |
| beliefs = [0.2, 0.3, 0.5] | |
| state = GameState( | |
| round_number=2, | |
| max_rounds=5, | |
| phase=GamePhase.PLAYING, | |
| target_value=4, | |
| evidence_history=evidence, | |
| current_beliefs=beliefs, | |
| most_likely_target=3, | |
| belief_entropy=1.5, | |
| ) | |
| assert state.target_value == 4 | |
| assert state.evidence_history == evidence | |
| assert state.current_beliefs == beliefs | |
| assert state.most_likely_target == 3 | |
| assert state.belief_entropy == 1.5 | |
| class TestBayesianGame: | |
| """Test the BayesianGame class.""" | |
| def test_initialization_default(self): | |
| """Test game initialization with default parameters.""" | |
| game = BayesianGame() | |
| assert game.dice_sides == 6 | |
| assert game.max_rounds == 10 | |
| assert game.environment.dice_sides == 6 | |
| assert game.belief_state.dice_sides == 6 | |
| assert game.game_state.phase == GamePhase.SETUP | |
| assert game.game_state.round_number == 0 | |
| assert game.game_state.max_rounds == 10 | |
| def test_initialization_custom(self): | |
| """Test game initialization with custom parameters.""" | |
| game = BayesianGame(dice_sides=8, max_rounds=15, seed=42) | |
| assert game.dice_sides == 8 | |
| assert game.max_rounds == 15 | |
| assert game.environment.dice_sides == 8 | |
| assert game.belief_state.dice_sides == 8 | |
| assert game.game_state.max_rounds == 15 | |
| def test_start_new_game_random_target(self): | |
| """Test starting new game with random target.""" | |
| game = BayesianGame(seed=42) | |
| state = game.start_new_game() | |
| assert state.phase == GamePhase.PLAYING | |
| assert state.round_number == 0 | |
| assert 1 <= state.target_value <= 6 | |
| assert len(state.evidence_history) == 0 | |
| assert len(state.current_beliefs) == 6 | |
| assert state.most_likely_target in range(1, 7) | |
| assert state.belief_entropy > 0 | |
| def test_start_new_game_specific_target(self): | |
| """Test starting new game with specific target.""" | |
| game = BayesianGame() | |
| state = game.start_new_game(target_value=4) | |
| assert state.phase == GamePhase.PLAYING | |
| assert state.target_value == 4 | |
| assert game.environment.get_target_value() == 4 | |
| def test_start_new_game_resets_state(self): | |
| """Test that starting new game resets previous state.""" | |
| game = BayesianGame(seed=42) | |
| # Start first game and play some rounds | |
| game.start_new_game(target_value=3) | |
| game.play_round() | |
| game.play_round() | |
| # Start new game | |
| state = game.start_new_game(target_value=5) | |
| assert state.target_value == 5 | |
| assert state.round_number == 0 | |
| assert len(state.evidence_history) == 0 | |
| assert len(game.belief_state.evidence_history) == 0 | |
| def test_play_round_not_playing(self): | |
| """Test playing round when not in playing phase.""" | |
| game = BayesianGame() | |
| # Game starts in setup phase | |
| with pytest.raises(ValueError, match="Game is not in playing phase"): | |
| game.play_round() | |
| def test_play_round_game_finished(self): | |
| """Test playing round when game is already finished.""" | |
| game = BayesianGame(max_rounds=1, seed=42) | |
| # Start game and play one round (should finish) | |
| game.start_new_game(target_value=3) | |
| game.play_round() | |
| # Try to play another round | |
| with pytest.raises(ValueError, match="Game is not in playing phase"): | |
| game.play_round() | |
| def test_play_round_updates_state(self): | |
| """Test that playing round updates game state correctly.""" | |
| game = BayesianGame(seed=42) | |
| game.start_new_game(target_value=3) | |
| initial_round_number = game.get_current_state().round_number | |
| # Play one round | |
| updated_state = game.play_round() | |
| assert updated_state.round_number == initial_round_number + 1 | |
| assert len(updated_state.evidence_history) == 1 | |
| assert len(updated_state.current_beliefs) == 6 | |
| assert updated_state.most_likely_target in range(1, 7) | |
| assert updated_state.belief_entropy >= 0 | |
| # Evidence should be valid | |
| evidence = updated_state.evidence_history[0] | |
| assert 1 <= evidence.dice_roll <= 6 | |
| # At least one basic comparison result should be present | |
| basic_results = {"higher", "lower", "same"} | |
| assert any(result in basic_results for result in evidence.comparison_results) | |
| def test_play_multiple_rounds(self): | |
| """Test playing multiple rounds.""" | |
| game = BayesianGame(max_rounds=5, seed=42) | |
| game.start_new_game(target_value=4) | |
| for expected_round in range(1, 6): | |
| state = game.play_round() | |
| assert state.round_number == expected_round | |
| assert len(state.evidence_history) == expected_round | |
| if expected_round < 5: | |
| assert state.phase == GamePhase.PLAYING | |
| else: | |
| assert state.phase == GamePhase.FINISHED | |
| def test_get_current_state(self): | |
| """Test getting current game state.""" | |
| game = BayesianGame() | |
| # Initial state | |
| state = game.get_current_state() | |
| assert state.phase == GamePhase.SETUP | |
| # After starting game | |
| game.start_new_game(target_value=2) | |
| state = game.get_current_state() | |
| assert state.phase == GamePhase.PLAYING | |
| assert state.target_value == 2 | |
| def test_is_game_finished(self): | |
| """Test checking if game is finished.""" | |
| game = BayesianGame(max_rounds=2, seed=42) | |
| # Initially not finished | |
| assert not game.is_game_finished() | |
| # Start game - still not finished | |
| game.start_new_game(target_value=3) | |
| assert not game.is_game_finished() | |
| # Play one round - still not finished | |
| game.play_round() | |
| assert not game.is_game_finished() | |
| # Play final round - now finished | |
| game.play_round() | |
| assert game.is_game_finished() | |
| def test_get_final_guess_accuracy_no_target(self): | |
| """Test getting final guess accuracy without target set.""" | |
| game = BayesianGame() | |
| with pytest.raises(ValueError, match="Target value not set"): | |
| game.get_final_guess_accuracy() | |
| def test_get_final_guess_accuracy(self): | |
| """Test getting final guess accuracy.""" | |
| game = BayesianGame(seed=42) | |
| game.start_new_game(target_value=3) | |
| # Play some rounds | |
| game.play_round() | |
| game.play_round() | |
| accuracy = game.get_final_guess_accuracy() | |
| # Should be probability assigned to target value 3 | |
| assert 0 <= accuracy <= 1 | |
| expected_accuracy = game.belief_state.get_belief_for_target(3) | |
| assert accuracy == expected_accuracy | |
| def test_was_final_guess_correct_no_target(self): | |
| """Test checking final guess correctness without target set.""" | |
| game = BayesianGame() | |
| with pytest.raises(ValueError, match="Target value not set"): | |
| game.was_final_guess_correct() | |
| def test_was_final_guess_correct(self): | |
| """Test checking if final guess was correct.""" | |
| game = BayesianGame(seed=42) | |
| game.start_new_game(target_value=3) | |
| # Play rounds until we get definitive evidence | |
| for _ in range(10): # Play enough rounds to get clear evidence | |
| if game.is_game_finished(): | |
| break | |
| game.play_round() | |
| is_correct = game.was_final_guess_correct() | |
| most_likely = game.game_state.most_likely_target | |
| assert isinstance(is_correct, bool) | |
| assert is_correct == (most_likely == 3) | |
| def test_get_game_summary(self): | |
| """Test getting game summary.""" | |
| game = BayesianGame(max_rounds=3, seed=42) | |
| game.start_new_game(target_value=4) | |
| # Play all rounds | |
| while not game.is_game_finished(): | |
| game.play_round() | |
| summary = game.get_game_summary() | |
| # Check all required fields | |
| assert summary["rounds_played"] == 3 | |
| assert summary["max_rounds"] == 3 | |
| assert summary["true_target"] == 4 | |
| assert summary["final_guess"] in range(1, 7) | |
| assert isinstance(summary["guess_correct"], bool) | |
| assert 0 <= summary["final_accuracy"] <= 1 | |
| assert summary["final_entropy"] >= 0 | |
| assert summary["evidence_count"] == 3 | |
| assert len(summary["final_beliefs"]) == 6 | |
| # Check that final beliefs are properly indexed (1-6) | |
| for i in range(1, 7): | |
| assert i in summary["final_beliefs"] | |
| def test_belief_updates_with_evidence(self): | |
| """Test that belief updates properly reflect evidence.""" | |
| game = BayesianGame(seed=42) | |
| game.start_new_game(target_value=1) # Low target for predictable evidence | |
| # Store initial beliefs for comparison | |
| _initial_beliefs = game.belief_state.get_current_beliefs() | |
| # Play several rounds | |
| states = [] | |
| for _ in range(5): | |
| if game.is_game_finished(): | |
| break | |
| state = game.play_round() | |
| states.append(state) | |
| # Beliefs should change as evidence accumulates | |
| final_beliefs = game.belief_state.get_current_beliefs() | |
| # Should not be uniform anymore (unless very unlikely) | |
| assert not all(abs(b - 1 / 6) < 1e-10 for b in final_beliefs) | |
| # Evidence should influence beliefs correctly | |
| for state in states: | |
| for evidence in state.evidence_history: | |
| if "higher" in evidence.comparison_results: | |
| # Target must be less than dice roll | |
| for _target in range(evidence.dice_roll, 7): | |
| # These targets should have reduced probability | |
| pass # Detailed verification would require complex logic | |
| def test_game_with_evidence_updates(self): | |
| """Test game behavior with evidence updates.""" | |
| game = BayesianGame(seed=42) | |
| game.start_new_game(target_value=3) | |
| # Apply evidence that changes beliefs | |
| update = BeliefUpdate(comparison_results=["higher"]) | |
| game.belief_state.update_beliefs(update) | |
| # Update game state to reflect the belief change | |
| game.game_state.most_likely_target = game.belief_state.get_most_likely_target() | |
| # Beliefs should have changed from uniform | |
| prob_1 = game.belief_state.get_belief_for_target(1) | |
| prob_6 = game.belief_state.get_belief_for_target(6) | |
| assert prob_1 > prob_6 # Lower targets should be more likely after "higher" | |
| assert game.belief_state.get_most_likely_target() in range(1, 7) | |
| assert 0 <= game.get_final_guess_accuracy() <= 1 | |
| def test_reproducibility_with_seed(self): | |
| """Test that games are reproducible with same seed.""" | |
| # Run two games with same seed | |
| game1 = BayesianGame(seed=42) | |
| game1.start_new_game(target_value=3) | |
| game2 = BayesianGame(seed=42) | |
| game2.start_new_game(target_value=3) | |
| # Play same number of rounds | |
| for _ in range(5): | |
| if game1.is_game_finished() or game2.is_game_finished(): | |
| break | |
| state1 = game1.play_round() | |
| state2 = game2.play_round() | |
| # Evidence should be identical | |
| assert len(state1.evidence_history) == len(state2.evidence_history) | |
| for ev1, ev2 in zip( | |
| state1.evidence_history, state2.evidence_history, strict=False | |
| ): | |
| assert ev1.dice_roll == ev2.dice_roll | |
| assert ev1.comparison_results == ev2.comparison_results | |
| # Beliefs should be identical | |
| assert state1.current_beliefs == state2.current_beliefs | |