コード例 #1
0
ファイル: views.py プロジェクト: markcharyk/tic-tac-toe
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})
コード例 #2
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