Ejemplo n.º 1
0
    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'
Ejemplo n.º 2
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)
Ejemplo n.º 3
0
    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"
Ejemplo n.º 4
0
 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')
Ejemplo n.º 5
0
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}"
        )
Ejemplo n.º 7
0
 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')
Ejemplo n.º 8
0
 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)
Ejemplo n.º 9
0
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})
Ejemplo n.º 10
0
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')
Ejemplo n.º 11
0
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])
Ejemplo n.º 12
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)
Ejemplo n.º 13
0
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')

Ejemplo n.º 14
0
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
Ejemplo n.º 15
0
 def setUp(self):
     self.b = Board()
Ejemplo n.º 16
0
 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])
Ejemplo n.º 17
0
 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))
Ejemplo n.º 18
0
 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))