def setUp(self): self.board = Board() self.overboard = Board() self.overboard.state[-4:, 3] = 'C' self.fullboard = Board() self.fullboard.state[3:, 2] = 'C' self.fullboard.state[:-3, 2] = 'P'
class BoardTest(TestCase): def setUp(self): self.board = Board() self.overboard = Board() self.overboard.state[-4:, 3] = "C" self.fullboard = Board() self.fullboard.state[3:, 2] = "C" self.fullboard.state[:-3, 2] = "P" def teardown(self): pass def test_default_board(self): """ Test that creating a board sets proper defaults """ board = Board() self.assertEqual(board.width, settings.BOARD_WIDTH, "Board width does not match default value") self.assertEqual(board.height, settings.BOARD_HEIGHT, "Board height does not match default value") self.assertEqual(board.turn, PLAYERS[0], "Board current turn does not match default value") self.assertEqual(board.state.size, board.height * board.width, "Board state does not match expected state") def test_board(self): """ Test creating a board with options """ board = Board(width=10, height=11) self.assertEqual(board.width, 10, "Board width does not match passed value") self.assertEqual(board.height, 11, "Board height does not match passed value") self.assertEqual(board.state.size, board.height * board.width, "Board state does not match expected state") def test_playcolumn_raises_InvalidPlayer_on_invalid_player(self): invalidPlayer = PLAYERS[abs(PLAYERS.index(self.board.turn) - 1)] self.assertRaises(e.InvalidPlayer, self.board.playcolumn, invalidPlayer, 3) def test_playcolumn_swaps_player_turn(self): currentPlayer = self.board.turn self.board.playcolumn(currentPlayer, 3) self.assertNotEqual(self.board.turn, currentPlayer, "Board player did not change") def test_playcolumn_changes_board_state(self): currentState = self.board.state.copy() self.board.playcolumn(self.board.turn, choice(range(self.board.width))) self.assertNotEqual( self.board.state.size, np.sum(currentState == self.board.state), "Board state did not change" ) def test_playcolumn_raises_GameOver_when_game_complete(self): self.assertRaises(e.GameOver, self.overboard.playcolumn, self.overboard.turn, 2) def test_playcolumn_raises_InvalidColumn_when_column_is_full(self): self.assertRaises(e.InvalidColumn, self.fullboard.playcolumn, self.fullboard.turn, 2)
def setUp(self): self.board = Board() self.overboard = Board() self.overboard.state[-4:, 3] = "C" self.fullboard = Board() self.fullboard.state[3:, 2] = "C" self.fullboard.state[:-3, 2] = "P"
def test_board(self): """ Test creating a board with options """ board = Board(width=10, height=11) self.assertEqual(board.width, 10, 'Board width does not match passed value') self.assertEqual(board.height, 11, 'Board height does not match passed value') self.assertEqual(board.state.size, board.height * board.width, 'Board state does not match expected state')
def index(request): (diff, players) = (None, 1) if request.method == 'POST': form = ConfigForm(request.POST) if form.is_valid(): diff = form.cleaned_data['difficulty'] players = form.cleaned_data['players'] # start a new board board = Board(difficulty=diff, players=players) request.session['board'] = board return render(request, 'game/index.html', {"board": board})
def test_board_default_state(self): board = Board() field_emptiness_statuses = { field_name: board.check_if_field_is_empty(field=field_name) for field_name in BOARD_FIELDS_EXPECTED } self.assertNotIn( False, field_emptiness_statuses.values(), f"in default state not all Board fields values were reported as empty:" f"reported: {field_emptiness_statuses}") for _field_name in BOARD_FIELDS_EXPECTED: _field_val = getattr(board, _field_name) self.assertEqual( _field_val, FIELD_EMPTY_VAL, f"Board in default state reported a non-empty `{_field_name}` value:" f"reported: {_field_val}, expected: {FIELD_EMPTY_VAL}") self.assertEqual(board.check_if_board_is_full(), (False, 0), "Board in default state reported to be full") self.assertFalse( board.win_board(), "Board in default state reported win condition as met") self.assertFalse( board.end_game, f"Board in default state reported game end condition to be True - `end_game`={board.end_game}" ) self.assertFalse( board.last_move, f"Board in default state reported last move dump as populated - `last_move`={board.last_move}" ) self.assertIsNone( board.game, f"Board in default state reported game as populated - `game`={board.game}" )
def test_default_board(self): """ Test that creating a board sets proper defaults """ board = Board() self.assertEqual(board.width, settings.BOARD_WIDTH, 'Board width does not match default value') self.assertEqual(board.height, settings.BOARD_HEIGHT, 'Board height does not match default value') self.assertEqual(board.turn, PLAYERS[0], 'Board current turn does not match default value') self.assertEqual(board.state.size, board.height * board.width, 'Board state does not match expected state')
def __init__(self, game, turn_no=0): self.board = None if turn_no: self.board = Board.objects.filter(game=game, turn_no=turn_no).get() if not self.board: # raise pass else: self.board = Board(game=game, turn_no=1, rows=self.rows, columns=self.columns, board=self.default_board_string) self._parse_state(self.board.board)
def play(request): if request.is_ajax(): try: space = int(request.POST['id']) board = Board.objects.get(pk=request.POST['board_id'][6:]) except KeyError: return HttpResponse('Error') except Board.DoesNotExist: raise Http404("That game doesn't seem to exist") try: board.make_move(space, 'X') except UnallowedError: data = {"msg": "That's not allowed!"} else: data = {} # Check if X's move ended the game if not board.check_for_end()[0]: O_space = _AI_move_random(board) data = {"O": O_space} ending = board.check_for_end() board.save() # Check if O's move ended the game if ending[0]: data.update({ "msg": ending[1]+' wins!\nRefresh to play again.', "end": "true"}) board.delete() # return a response with the appropriate JSON data return HttpResponse( json.dumps(data), content_type="application/json") elif request.method == 'GET': # Create a new board and put it in the database new_board = Board() new_board.save() return render(request, 'game/game.html', {'board_id': new_board.pk})
class MakeMoveTest(TestCase): def setUp(self): self.b = Board() def test_X_move(self): self.b.make_move(0, 'X') self.assertEqual(self.b.spaces, u'X ') def test_O_move(self): self.b.spaces = u'X ' self.b.make_move(4, 'O') self.assertEqual(self.b.spaces, u'X O ') def test_off_board_move(self): with self.assertRaises(UnallowedError): self.b.make_move(10, 'X') def test_filled_space(self): self.b.spaces = u' X ' with self.assertRaises(UnallowedError): self.b.make_move(4, 'O')
class CheckForEndTest(TestCase): def setUp(self): self.b = Board() def test_X_wins(self): self.b.spaces = u'X O XO X' returned_tup = self.b.check_for_end() self.assertTrue(returned_tup[0]) self.assertEqual(returned_tup[1], 'X') def test_O_wins(self): self.b.spaces = u'OOOX XX ' returned_tup = self.b.check_for_end() self.assertTrue(returned_tup[0]) self.assertEqual(returned_tup[1], 'O') def test_cats_game(self): self.b.spaces = u'OXOOXXXOX' returned_tup = self.b.check_for_end() self.assertTrue(returned_tup[0]) self.assertEqual(returned_tup[1], 'The cat') def test_Xs_turn(self): self.b.spaces = u'XX O O ' returned_tup = self.b.check_for_end() self.assertFalse(returned_tup[0]) def test_Os_turn(self): self.b.spaces = u'XX O ' returned_tup = self.b.check_for_end() self.assertFalse(returned_tup[0]) def test_start_of_game(self): self.b.spaces = u' ' returned_tup = self.b.check_for_end() self.assertFalse(returned_tup[0])
class BoardTest(TestCase): def setUp(self): self.board = Board() self.overboard = Board() self.overboard.state[-4:, 3] = 'C' self.fullboard = Board() self.fullboard.state[3:, 2] = 'C' self.fullboard.state[:-3, 2] = 'P' def teardown(self): pass def test_default_board(self): """ Test that creating a board sets proper defaults """ board = Board() self.assertEqual(board.width, settings.BOARD_WIDTH, 'Board width does not match default value') self.assertEqual(board.height, settings.BOARD_HEIGHT, 'Board height does not match default value') self.assertEqual(board.turn, PLAYERS[0], 'Board current turn does not match default value') self.assertEqual(board.state.size, board.height * board.width, 'Board state does not match expected state') def test_board(self): """ Test creating a board with options """ board = Board(width=10, height=11) self.assertEqual(board.width, 10, 'Board width does not match passed value') self.assertEqual(board.height, 11, 'Board height does not match passed value') self.assertEqual(board.state.size, board.height * board.width, 'Board state does not match expected state') def test_playcolumn_raises_InvalidPlayer_on_invalid_player(self): invalidPlayer = PLAYERS[abs(PLAYERS.index(self.board.turn) - 1)] self.assertRaises(e.InvalidPlayer, self.board.playcolumn, invalidPlayer, 3) def test_playcolumn_swaps_player_turn(self): currentPlayer = self.board.turn self.board.playcolumn(currentPlayer, 3) self.assertNotEqual(self.board.turn, currentPlayer, 'Board player did not change') def test_playcolumn_changes_board_state(self): currentState = self.board.state.copy() self.board.playcolumn(self.board.turn, choice(range(self.board.width))) self.assertNotEqual(self.board.state.size, np.sum(currentState == self.board.state), 'Board state did not change') def test_playcolumn_raises_GameOver_when_game_complete(self): self.assertRaises(e.GameOver, self.overboard.playcolumn, self.overboard.turn, 2) def test_playcolumn_raises_InvalidColumn_when_column_is_full(self): self.assertRaises(e.InvalidColumn, self.fullboard.playcolumn, self.fullboard.turn, 2)
from django.shortcuts import render from django.http import HttpResponse from game.models import Player, Board, PlayerEncoder, BoardEncoder from django.urls import reverse_lazy from django.views.generic.edit import CreateView, UpdateView import json board = Board() def index(request): board.getPlayers() board.makeMove() return HttpResponse(json.dumps(board, cls=BoardEncoder)) # Create your views here. def get_player(request, id): player = Player.objects.filter(id=id) if (len(player) == 1): return HttpResponse(json.dumps(player[0], cls=PlayerEncoder)) else: return HttpResponse("No such player") class PlayerCreate(CreateView): model = Player fields = '__all__' success_url = reverse_lazy('index')
class StandardBoard: data = [] rows = 11 columns = 16 cells = [] G, T, R = 'G','T', 'R' C = 'T*' default_board = (G, G, G, G, R, R, R, R, R, G, T, G, R, G, G, G, G, C, G, G, R, G, G, G, G, G, G, G, R, G, G, C, G, G, G, R, R, T, G, G, G, G, G, G, R, R, G, G, R, R, R, R, G, G, G, G, G, G, G, G, G, R, R, R, G, G, G, G, G, G, G, G, G, G, G, G, G, T, R, R, G, G, G, G, G, G, G, G, G, G, G, G, G, G, R, G, R, R, R, R, G, G, G, G, T, G, G, G, R, R, R, G, G, C, G, R, R, R, R, G, G, G, G, G, R, G, G, G, G, G, G, G, G, G, R, R, R, R, R, R, R, G, C, G, G, G, G, G, G, T, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, T, G, G, G, G, G,) default_board_string = '|'.join(default_board) def __init__(self, game, turn_no=0): self.board = None if turn_no: self.board = Board.objects.filter(game=game, turn_no=turn_no).get() if not self.board: # raise pass else: self.board = Board(game=game, turn_no=1, rows=self.rows, columns=self.columns, board=self.default_board_string) self._parse_state(self.board.board) def _db_form(self): return '|'.join([ cell.db_form() for cell in self.cells]) def _parse_state(self, board_str): def convert(cell_str): if cell_str.startswith('G'): if '!' in cell_str: return Ground(special=Catastrophe()) elif '?' in cell_str: g = Ground(special=Unification()) g.special.piece = cell_str[-1] return g # XXX # civ_type = cell_str[2] # if civ_type == 's': # return Ground(piece=SettlementCiv(), special=Unification()) # elif civ_type == 't': # return Ground(piece=TempleCiv(), special=Unification()) # elif civ_type == 'm': # return Ground(piece=MerchantCiv(), special=Unification()) else: return Ground() elif cell_str.startswith('R'): if '!' in cell_str: return River(special=Catastrophe()) elif '?' in cell_str: return River(piece=FarmCiv(), special=Unification()) else: return River() elif cell_str.startswith('s'): return Ground(piece=SettlementCiv()) elif cell_str.startswith('t'): return Ground(piece=TempleCiv()) elif cell_str.startswith('f'): return River(piece=FarmCiv()) elif cell_str.startswith('m'): return Ground(piece=MerchantCiv()) elif cell_str.startswith('T'): if cell_str.startswith('T*'): return Ground(piece=TempleCiv(treasure=Treasure(is_corner=True))) else: return Ground(piece=TempleCiv(treasure=Treasure(is_corner=False))) elif cell_str.startswith('r'): ruler_type = cell_str[2] ruler_player_no = cell_str[1] if ruler_type == 's': return Ground(piece=SettlementRuler(ruler_player_no)) elif ruler_type == 't': return Ground(piece=TempleRuler(ruler_player_no)) elif ruler_type == 'f': return Ground(piece=FarmRuler(ruler_player_no)) elif ruler_type == 'm': return Ground(piece=MerchantRuler(ruler_player_no)) elif cell_str.startswith('M'): pass self.cells = [ convert(x) for x in board_str.split('|')] self.data = [ {} for _ in self.cells ] # XXX todo: unit test this function def treasure_to_claim(self): for region in self.pieces_by_region: player = None for type, player_no, _ in region['rulers']: if type.split("-")[1] == 'merchant': player = player_no if len(region['treasures']['corner']) + len(region['treasures']['normal']) > 1 and player: treasure_info = { 'player_no': player, 'corner': region['treasures']['corner'], 'normal': region['treasures']['normal'], } treasure_info.update(self._analyze_treasure(treasure_info)) return treasure_info return {} # XXX todo: unit test this function def _analyze_treasure(self, treasure): num_corner = len(treasure['corner']) num_normal = len(treasure['normal']) num_claim = num_corner + num_normal - 1 must_choose, can_choose, num_choose = [], [], 0 if num_corner > 0: if num_corner == num_claim: must_choose = treasure['corner'] can_choose = [] num_choose = 0 elif num_corner < num_claim: must_choose = treasure['corner'] can_choose = treasure['normal'] num_choose = num_claim - num_corner elif num_corner > num_claim: must_choose = [] can_choose = treasure['corner'] num_choose = num_claim else: must_choose = [] can_choose = treasure['normal'] num_choose = num_claim return { 'must_choose': must_choose, 'can_choose': can_choose, 'num_choose': num_choose } def find_unification_tile(self): for cell_no, cell in enumerate(self.cells): if cell.special and ('?' in cell.special.db_form()): return cell_no return None def is_ruler_placed(self, ruler_type, player_no): for cell_no, cell in enumerate(self.cells): if cell.piece and (cell.piece.db_form() == 'r' + player_no + ruler_type[6]): return cell_no return None def get_cell_no_for_unification(self): for cell_no, cell in enumerate(self.cells): if cell.special and ('?' in cell.db_form()): return [cell_no] return [] def get_cell_no_for_civ(self, color): cell_nos = [] for cell_no, cell in enumerate(self.cells): if cell.piece and (cell.piece.db_form() == color): cell_nos.append(cell_no) return cell_nos def get_cell_no_for_player_no_and_ruler(self, player_no, color): player_no = int(player_no) for cell_no, cell in enumerate(self.cells): if cell.piece and (cell.piece.db_form()[-1] == color) and (cell.piece.db_form()[0] == 'r') and (int(cell.piece.player_no) == player_no): return cell_no return -1 def place_unification(self, cell_no, civ): self.cells[cell_no].special = Unification() # XXX self.cells[cell_no].special.piece = civ.css_class_name() def save(self): self.board.board = self._db_form() self.board.save() def __iter__(self): return self.cells.__iter__() def __len__(self): return self.cells.__len__() def __getitem__(self, x): return self.cells.__getitem__(x) def __setitem__(self, x, y): return self.cells.__setitem__(x, y) def get_point(self, cell_no, civ): try: region = self.data[cell_no]['adjacent_kingdoms'][0] except IndexError: return None for name, player_no, _ in self.pieces_by_region[region]['rulers']: if name == 'ruler-' + civ.css_class_name(): return player_no for name, player_no, _ in self.pieces_by_region[region]['rulers']: if name == 'ruler-settlement': return player_no return None def add_ruler(self, cell_no, ruler, player_no): piece = _convert_ruler(ruler, player_no) self.cells[cell_no].piece = piece def remove_ruler(self, cell_no): self[cell_no].piece = None def add_civ(self, cell_no, civ): self.cells[cell_no].piece = civ def external_war_removal(self, region, civ): count = 0 for type, _, cell_no in self.pieces_by_region[region]['rulers']: if type.split("-")[1] == civ: self[cell_no].piece = None count += 1 for cell_no in self.pieces_by_region[region][civ]: mark = [] def assign_mark(index): mark.append(index) # XXX Check for treasure, too if civ == 'temple': pred = lambda index: self[index].has_ruler() do_on_adjacent_cells(cell_no, self, pred, assign_mark) if not mark: self[cell_no].piece = None count += 1 return count
def setUp(self): self.b = Board()
def test_AI_move_middle_of_game(self): """Test the AI placing a move on a partially-filled board""" b = Board() b.spaces = 'XXO X O ' self.assertIn(_AI_move_random(b), [3, 5, 6, 8])
def test_AI_move_empty(self): """Test the AI placing a move on an empty board""" b = Board() b.spaces = ' ' self.assertIn(_AI_move_random(b), range(9))
def test_AI_move_full(self): """Test the AI trying to move on a full board""" b = Board() b.spaces = 'XXOOOXXOX' self.assertIsNone(_AI_move_random(b))