def test_engine_round_complete(): p1_field_str = '0,0,0,0;0,0,0,0;2,0,0,2;2,2,0,2;2,2,2,2;2,2,2,2;3,3,3,3' p2_field_str = '0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;2,0,0,2;2,0,2,2;2,2,2,0' field1 = Field.from_str(p1_field_str, score_keeper=ScoreKeeper(11, 2)) field2 = Field.from_str(p2_field_str, score_keeper=ScoreKeeper(3, 1)) mock_block_source = iter([OBlock, IBlock, TBlock]) engine = Engine((field1, field2), ('p1', 'p2'), game_state=GameState(mock_block_source, starting_round=3), settings=_test_settings) assert _read_report(engine) == ( 'update game round 3\n' 'update game this_piece_type O\n' 'update game next_piece_type I\n' 'update game this_piece_position 4,-1\n' 'update p1 row_points 11\n' 'update p1 combo 2\n' 'update p1 field\n' '{p1_field}\n' 'update p2 row_points 3\n' 'update p2 combo 1\n' 'update p2 field\n' '{p2_field}\n' ).format(p1_field=p1_field_str, p2_field=p2_field_str) engine.complete_round() # Player 1 completes 2 rows, winning 2 (+2) points. A solid row is # added to player 2's field. Player 1's combo continues, player 2's is # lost. New blocks are selected. The round number is now assert _read_report(engine) == ( 'update game round 4\n' 'update game this_piece_type I\n' 'update game next_piece_type T\n' 'update game this_piece_position 4,-1\n' 'update p1 row_points 15\n' 'update p1 combo 3\n' 'update p1 field\n' '0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;2,0,0,2;2,2,0,2;3,3,3,3\n' 'update p2 row_points 3\n' 'update p2 combo 0\n' 'update p2 field\n' '0,0,0,0;0,0,0,0;0,0,0,0;2,0,0,2;2,0,2,2;2,2,2,0;3,3,3,3\n' )
def test_ending_game_with_drop(): field = Field.from_str('0,0,0,0;3,3,3,3') oblock = OBlock(field) oblock.position = 1, -1 with pytest.raises(GameOver): oblock.drop()
def test_row_completion(): """update should delete any full rows and return the number removed""" score_keeper = ScoreKeeper() field = Field.from_str('0,0;0,0', score_keeper) field.remove_completed_rows() assert score_keeper.score == 0 assert score_keeper.combo == 0 assert str(field) == '0,0;0,0' field = Field.from_str('0,0,0;0,2,0;2,2,2', score_keeper) field.remove_completed_rows() assert score_keeper.score == 1 assert score_keeper.combo == 1 assert str(field) == '0,0,0;0,0,0;0,2,0' field = Field.from_str('0,0,0,0,0;2,2,2,2,2;2,0,2,2,2;2,2,2,2,2;0,0,0,2,0', score_keeper) field.remove_completed_rows() assert score_keeper.score == 4 assert score_keeper.combo == 2 assert str(field) == '0,0,0,0,0;0,0,0,0,0;0,0,0,0,0;2,0,2,2,2;0,0,0,2,0'
def test_invalid_rotations(): """cannot rotate blocks if they will collide with another""" field = Field.from_str('0,0,0,0;0,0,0,0;0,0,0,2;0,0,0,2;0,0,0,2;0,0,0,2') # Vertical I blocks placed next to each other block = IBlock(field).rotate_cw() block.position = 0, 2 assert str(field) == '0,0,0,0;0,0,0,0;0,0,1,2;0,0,1,2;0,0,1,2;0,0,1,2' # Block unable to rotate from this position with pytest.raises(InvalidBlockRotation): block.rotate_ccw() assert str(field) == '0,0,0,0;0,0,0,0;0,0,1,2;0,0,1,2;0,0,1,2;0,0,1,2'
def test_player_reporter(): """reporting player status""" sk = ScoreKeeper(15, 2) f = Field.from_str('0,0,0,0;0,0,2,2;0,2,2,2;3,3,3,3', sk) reporter = PlayerReporter('first_player', f) assert _read_report(reporter) == ( 'update first_player row_points 15\n' 'update first_player combo 2\n' 'update first_player field\n' '0,0,0,0;0,0,2,2;0,2,2,2;3,3,3,3\n' )
def test_invalid_block_placement(): """cannot place blocks on top of each other or outside field bounds""" exp_str = '0,0,0,0;0,0,0,0;0,0,0,0;0,0,0,0;2,2,0,0;2,2,0,0' field = Field.from_str(exp_str) block = OBlock(field) # Place outside the field with pytest.raises(InvalidBlockPosition): block.position = -1, 4 # Overlapping blocks with pytest.raises(InvalidBlockPosition): block.position = 0, 4 assert str(field) == exp_str
def test_raising(): """raising the base should add a solid row (3s) which cannot be removed. if blocks are pushed above the upper bound, the game ends """ score_keeper = ScoreKeeper() field = Field.from_str('0,0,0,0;0,0,2,2;2,2,2,0', score_keeper) field.raise_base() assert str(field) == '0,0,2,2;2,2,2,0;3,3,3,3' field.remove_completed_rows() assert str(field) == '0,0,2,2;2,2,2,0;3,3,3,3' with pytest.raises(GameOver): field.raise_base() assert score_keeper.score == 0 assert score_keeper.combo == 0
def test_from_str(): """instantiate a field from its string representation""" assert str(Field.from_str('0,0;0,0')) == '0,0;0,0' assert str(Field.from_str('0,0,2;0,0,2')) == '0,0,2;0,0,2' with_solid_row = Field.from_str('0,0,2;3,3,3') assert str(with_solid_row) == '0,0,2;3,3,3'