예제 #1
0
def _start_new_game() -> OthelloLogic.Game:
    """ Asks the user for a default or custom gameboard; if 'default' is chosen, options are an 8x8 board,
        most discs wins, black starts, and white is in the top-left corner of the starting layout;
        Else, prompts the user for custom options
        :return: Game object
    """
    while True:
        boardtype = input('[Default] or [custom] board?: ').strip().lower()

        if boardtype == 'default':
            return OthelloLogic.Game()

        elif boardtype == 'custom':
            rows = int(
                _get_game_option_input(
                    'rows', ['4', '6', '8', '10', '12', '14', '16']))
            cols = int(
                _get_game_option_input(
                    'cols', ['4', '6', '8', '10', '12', '14', '16']))
            starting_player = _get_game_option_input('starting player',
                                                     ['black', 'white'])
            corner_start_player = _get_game_option_input(
                'corner color', ['black', 'white'])
            win_type = _get_game_option_input('win type', ['most', 'least'])

            return OthelloLogic.Game(rows, cols, win_type, starting_player,
                                     corner_start_player)

        else:
            print('Invalid input.')
예제 #2
0
def isGameEnd(board):
    """ゲームが終了したかどうか判定する
    
    Args:
       board ${1:arg1}

    Returns:
        bool $0

    """
    boardSize = len(board)
    currentPiece = len([cell for line in board for cell in line if cell != 0])
    # 全てのマスが埋まった場合
    if currentPiece == boardSize**2:
        return True

    # 最終手で最後の人マスを打てる場合
    if currentPiece == (boardSize**2) - 1:
        if OthelloLogic.getMoves(board, 1, boardSize) != []:
            return False

    # 双方打つ手なし(互いにパス)
    nextBoard = deepcopy(board)
    if OthelloLogic.getMoves(nextBoard, 1, boardSize) == []:
        if OthelloLogic.getMoves(nextBoard, -1, boardSize) == []:
            return True

    return False
예제 #3
0
def before_complete(board, moves, turn, player, end_turn):
    tmp_board = copy.deepcopy(board)
    if len(moves) == 0:
        player *= -1
        moves = Ol.getMoves(board, player, size=8)
    if len(moves) == 0:
        return None, weight_check(board)

    ans_move = moves[0]

    if turn == 60 or turn == end_turn:
        next_board = Ol.execute(tmp_board, ans_move, player, size=8)
        return ans_move, weight_check(next_board)

    ans_weight = -1000
    sum_weight = 0

    for move in moves:
        next_board = Ol.execute(tmp_board, move, player, size=8)
        next_moves = Ol.getMoves(next_board, player * -1, size=8)
        next_move, next_weight = before_complete(next_board, next_moves,
                                                 turn + 1, player * -1,
                                                 end_turn)
        if ans_weight < next_weight:
            ans_weight = next_weight
            ans_move = move
        sum_weight += next_weight
    ave_weight = float(sum_weight / len(moves))

    if player == 1:
        return ans_move, ans_weight
    else:
        return ans_move, ave_weight
예제 #4
0
def complete(board, moves, turn, player):
    tmp_board = copy.deepcopy(board)
    if len(moves) == 0:
        player *= -1
        moves = Ol.getMoves(board, player, 8)
    if len(moves) == 0:
        return None, win_rate(board)

    ans_move = moves[0]

    if turn == 60:
        next_board = Ol.execute(tmp_board, ans_move, player, 8)
        return ans_move, win_rate(next_board)

    w_rate = 0
    l_rate = 1
    sum_rate = 0
    for move in moves:
        next_board = Ol.execute(tmp_board, move, player, 8)
        next_moves = Ol.getMoves(next_board, player * -1, 8)
        next_move, next_rate = complete(next_board, next_moves, turn + 1,
                                        player * -1)
        if w_rate < next_rate:
            w_rate = next_rate
            ans_move = move
        if l_rate > next_rate:
            l_rate = next_rate
        sum_rate += next_rate
    ave_rate = float(sum_rate / len(moves))

    if player == 1:
        return ans_move, w_rate
    else:
        return None, ave_rate
예제 #5
0
def open_rate_exception(board, moves):
    message = "open_rate_exception: success!"

    danger = [
        [1, 1],
        [1, 6],
        [6, 1],
        [6, 6]
    ]

    list_first = [
        [0, 0],
        [7, 0],
        [7, 7],
        [0, 7]
    ]

    ans_move = moves[0]
    success_frag = 0
    for move in moves:
        if move in danger:
            continue
        tmp_board = copy.deepcopy(board)
        next_board = Ol.execute(tmp_board, move, player=1, size=8)
        next_moves = Ol.getMoves(next_board, player=-1, size=8)
        for next_move in next_moves:
            if next_move in list_first:
                continue
        ans_move = move
        success_frag = 1
    if success_frag == 0:
        message = "open_rate_exception: failure..."
    return ans_move, message
예제 #6
0
def getAction(board, moves):
    ans = moves[0]
    tmp = 0
    for move in moves:
        next_board = ol.execute(board, move, 1, 8)
        next_moves = ol.getMoves(next_board, -1, 8)
        if tmp < len(next_moves):
            ans = move
    return ans
예제 #7
0
def getAction(board, moves):
    # オセロ番のサイズを変数に格納
    board_size = len(board[0])
    # オセロ盤の角の座標を配列に格納
    squares = [
        [0, board_size - 1],
        [board_size - 1, 0],
        [0, board_size - 1],
        [board_size - 1, board_size - 1],
    ]

    # もしも角がとれるなら角に手を打つ
    # for文で角の座標が引数moves内に存在するかどうかを調べる
    for s in squares:
        if s in moves:
            index = moves.index(s)
            return moves[index]

    # 相手の合法手の最小数を格納する変数(最小値なので初期値は適当に大きく)
    min_enemy_moves_length = 100
    # 返す手のindex(配列の添字)
    index = 0

    # for文で全ての手を打ってみる
    for m in moves:

        # 選択した手を打つ関数
        # 関数:execute
        # 返り値:盤面の状況(ちょうどこのOthelloActionの引数であるboardと同じ感じ)
        # 引数:board:(盤面の状態),move:打つ手(moves配列の中身),player:打つプレイヤー(1だと自分,-1だと相手),size:オセロ盤のサイズ

        # 引数として渡すboardにはdeepcopy関数を使用してください!!
        # deepcopyをしないでboardを渡すとpythonの仕様でおかしなことになります(設計が悪かったですごめんなさい)
        # 詳しくはオブジェクトIDで調べてもらえば...!
        board_next = OthelloLogic.execute(copy.deepcopy(board), m, 1,
                                          board_size)

        # 自分の手を打った後の相手の合法手を取得する関数
        # 関数:getMoves
        # 返り値:moves(選択したプレイヤーの合法手配列)
        # 引数:board(盤面の状態),player(どちらのプレイヤーの合法手を取得するか、1だと自分,-1だと相手,size:オセロ盤の大きさ)
        moves_next = OthelloLogic.getMoves(copy.deepcopy(board_next), -1,
                                           board_size)

        # 取得した相手の合法手の数が現在の最小値よりも低ければ最小値を更新
        if min_enemy_moves_length > len(moves_next):
            min_enemy_moves_length = len(moves_next)
            # 返す手のindexを更新
            index = moves.index(m)

    # 最小値の配列indexを返却して手を実行
    return moves[index]
예제 #8
0
def complete(board, moves, turn, player):
    tmp_board = copy.deepcopy(board)
    if len(moves) == 0:
        player *= -1
        moves = Ol.getMoves(board, player, 8)
    if len(moves) == 0:
        rate = win_rate(board)
        return None, rate, rate

    ans_move = moves[0]

    if turn == 60:
        next_board = Ol.execute(tmp_board, ans_move, player, 8)
        rate = win_rate(next_board)
        return ans_move, rate, rate

    w_rate = 0
    l_rate = 1
    sum_rate = 0
    ave_move = moves[0]
    ave_rate_max = 0
    for move in moves:
        # tmp_board = copy.deepcopy(board)
        # copy.deepcopyよりforで回した方が早い?
        for h in range(8):
            for w in range(8):
                tmp_board[h][w] = board[h][w]
        next_board = Ol.execute(tmp_board, move, player, 8)
        next_moves = Ol.getMoves(next_board, player * -1, 8)
        next_move, next_rate, next_ave_rate = complete(next_board, next_moves,
                                                       turn + 1, player * -1)
        if w_rate < next_rate:
            w_rate = next_rate
            ans_move = move
        if l_rate > next_rate:
            l_rate = next_rate
        if ave_rate_max < next_ave_rate:
            ave_move = move
            ave_rate_max = next_ave_rate
        sum_rate += next_ave_rate
    ave_rate = float(sum_rate / len(moves))

    if player == 1:
        if w_rate == 0:
            return ave_move, w_rate, ave_rate
        else:
            return ans_move, w_rate, ave_rate
    else:
        return None, l_rate, ave_rate
예제 #9
0
def evaluationFunc(board, target, size):
    nextBoard = OthelloLogic.execute(copy.deepcopy(board), target, 1, size)

    boardScore = 0
    for i in range(8):
        for j in range(8):
            boardScore = boardScore + util.getDistance([4, 4],
                                                       [i, j]) * board[i][j]
    return boardScore
예제 #10
0
def complete(board, moves, turn, player):
    tmp_board = copy.deepcopy(board)
    if len(moves) == 0:
        player *= -1
        moves = Ol.getMoves(board, player, 8)
    if len(moves) == 0:
        rate = win_rate(board)
        return None, rate

    ans_move = moves[0]

    if turn == 60:
        next_board = Ol.execute(tmp_board, ans_move, player, 8)
        rate = win_rate(next_board)
        return ans_move, rate

    w_rate = 0
    l_rate = 1
    for move in moves:
        # tmp_board = copy.deepcopy(board)
        # copy.deepcopyよりforで回した方が早い?
        for h in range(8):
            for w in range(8):
                tmp_board[h][w] = board[h][w]
        next_board = Ol.execute(tmp_board, move, player, 8)
        next_moves = Ol.getMoves(next_board, player * -1, 8)
        next_move, next_rate = complete(next_board, next_moves, turn + 1, player * -1)

        # 2021/01/09追加
        if player == 1 and next_rate == 1:
            return move, next_rate
        elif player == -1 and next_rate == 0:
            return None, next_rate

        if w_rate < next_rate:
            w_rate = next_rate
            ans_move = move
        if l_rate > next_rate:
            l_rate = next_rate

    if player == 1:
        return ans_move, w_rate
    else:
        return None, l_rate
예제 #11
0
def evalutionTree(board, player, boardSize, currentDepth=1):
    moves = OthelloLogic.getMoves(board, player, boardSize)

    # パスの時
    if moves == []:
        return evalutionTree(deepcopy(board), player * -1, boardSize)

    scores = []
    for move in moves:
        nextBoard = deepcopy(board)
        OthelloLogic.execute(nextBoard, move, player, boardSize)

        if util.isGameEnd(nextBoard):
            currentPlayer = 1 if currentDepth % 2 == 1 else -1
            scores.append(
                util.getBoardScore(deepcopy(nextBoard), currentPlayer))
        else:
            scores.append(
                evalutionTree(nextBoard, player * -1, boardSize,
                              currentDepth + 1))
    return min(scores)
예제 #12
0
def open_rate(board, moves):
    danger = [[1, 0], [1, 1], [0, 1], [6, 0], [7, 1], [6, 1], [7, 6], [6, 6],
              [6, 7], [1, 7], [0, 6], [1, 6]]

    list_first = [[0, 0], [7, 0], [7, 7], [0, 7]]

    del_ls = []
    for i in range(4):
        if board[list_first[i][0]][list_first[i][1]] == 1:
            del_ls.append(i)
    for i in del_ls:
        for j in range(i * 3, (i * 3) + 3):
            list_first.append(danger[j])
    del_ls.sort(reverse=True)
    for i in del_ls:
        del danger[(i * 3):((i * 3) + 3)]

    vectors = [[-1, -1], [0, -1], [1, -1], [-1, 0], [1, 0], [-1, 1], [0, 1],
               [1, 1]]

    ans_move = moves[0]
    ans_rate = 100

    for move in moves:
        if move in danger:
            continue
        elif move in list_first:
            return move, "great!"
        rate = 0
        zero_board = [[0 for _ in range(8)] for _ in range(8)]
        tmp_board = copy.deepcopy(board)
        next_board = Ol.execute(tmp_board, move, player=1, size=8)
        for h in range(8):
            for w in range(8):
                if board[h][w] == -1 and next_board[h][w] == 1:
                    for vec in vectors:
                        moved_index = [int(h + vec[0]), int(w + vec[1])]
                        if 0 <= moved_index[0] <= 7 and 0 <= moved_index[
                                1] <= 7:
                            zero_board[moved_index[0]][moved_index[1]] = 1
        for h in range(8):
            for w in range(8):
                if board[h][w] == 0 and zero_board[h][w] == 1:
                    rate += 1
        if rate < ans_rate:
            ans_rate = rate
            ans_move = move

    if ans_rate == 100:
        return open_rate_exception(board, moves)
    else:
        return ans_move, ans_rate
예제 #13
0
파일: OthelloGUI.py 프로젝트: walg/Projects
    def _read_information(self):
        '''reads in the information to create the gamestate from the information
           module'''
        self._info = Information()
        self._info.start()

        self._rows = self._info.rows
        self._columns = self._info.columns
        self._starting_color = self._info.starting_color
        self._seed_color = self._info.seed_color
        self._win_type = self._info.win_type

        self.gamestate = OthelloLogic.Gameboard(self._rows, self._columns,
                                                self._starting_color,
                                                self._seed_color,
                                                self._win_type)
예제 #14
0
def lern(board, moves):
    """

    Args:
       board arg1

    Returns:


    """
    boardSize = len(board)
    minScore = boardSize**2
    minScoreMove = moves[0]

    # 最終手の場合探索を行わない
    if util.getOnBoardPieces(board) == (boardSize**2) - 1:
        moves = OthelloLogic.getMoves(board, 1, boardSize)
        return moves[0]

    # 自分がパスで相手は打てる時
    if len(moves) == 1:
        return moves[0]
    if len(moves) == 0:
        if util.isGameEnd(deepcopy(board)):
            return moves[0]

    params = []
    for move in moves:
        params.append((deepcopy(board), move, boardSize))

    results = []
    with ProcessPoolExecutor() as executor:
        results = list(executor.map(evalFunc, params))

    # min
    for i in range(len(results)):
        if results[i] <= minScore:
            minScore = results[i]
            minScoreMove = moves[i]

    pprint(results)
    pprint(moves)
    return minScoreMove
예제 #15
0
def ab(board, moves, lim, a, b, side):
    # print(moves)
    if lim == 0:
        return calc_eval_score(board)
    """
    if len(moves) == 0:
        pass
        eval = -ab(board)
    """
    for move in moves:
        # print(move)
        nb = get_next_board(board, move, -side)
        enemy_hand = ol.getMoves(nb, -SIDE, SIZE)
        eval = -ab(board, enemy_hand, lim - 1, -b, -a, -side)
        a = max(a, eval)

        if a >= b:
            return a

    return a
예제 #16
0
import OthelloAction
import OthelloLogic

#sizeを変更することでテストプレイする盤面の大きさを変更できます。
#size = 4
#size = 6
size = 8
board = [[0 for i in range(size)] for j in range(size)]

board[int(size/2)-1][int(size/2)-1] = 1;
board[int(size/2)][int(size/2)-1]=-1;
board[int(size/2)-1][int(size/2)]=-1;
board[int(size/2)][int(size/2)]=1;

player = -1
moves = OthelloLogic.getMoves(board,player,size)
while(True):
	if(player == -1):
		action = OthelloAction.getAction(OthelloLogic.getReverseboard(board),moves)
	else:
		action = OthelloAction.getAction(board,moves)
	if(not (action in moves)):
		print(board)
		print('合法手ではない手が打たれました' + action)
		exit()
	board = OthelloLogic.execute(board,action,player,size)
	OthelloLogic.printBoard(board)
	print('現在の合法手一覧')
	print(moves)
	moves = OthelloLogic.getMoves(board,player*-1,size)
	if(len(moves) == 0):
예제 #17
0
    print('エラーが発生しました。')
    exit()

data = r.json()
roomid = data['id']
player = data['player']
board = []
payload = {}

if (player == 1):
    payload = {'player': player}
    r = requests.post(base_url + "wait_for_player/" + roomid,
                      data=payload,
                      headers=headers)
    data = r.json()
    OthelloLogic.printBoard(json.loads(data['board']))
    board = json.loads(data['board'])
    moves = json.loads(data['moves'])
else:
    OthelloLogic.printBoard(json.loads(data['board']))
    rev_board = json.loads(data['board'])
    board = json.loads(data['board'])
    for x in range(len(rev_board)):
        for y in range(len(rev_board)):
            board[x][y] = rev_board[x][y] * -1
    moves = json.loads(data['moves'])

action = json.dumps(OthelloAction.getAction(board, moves))
payload = {'action': action, 'player': player}

while (True):
예제 #18
0
def evalFunc(params):
    (board, move, boardSize) = params

    OthelloLogic.execute(board, move, 1, boardSize)
    return evalutionTree(board, -1, boardSize)
예제 #19
0
def middle_check(board, moves):
    left_ls = [
        [0, 0],
        [0, 1],
        [0, 2],
        [0, 3],
        [0, 4],
        [0, 5],
        [0, 6],
        [0, 7],
    ]

    right_ls = [
        [7, 0],
        [7, 1],
        [7, 2],
        [7, 3],
        [7, 4],
        [7, 5],
        [7, 6],
        [7, 7],
    ]

    up_ls = [
        [0, 0],
        [1, 0],
        [2, 0],
        [3, 0],
        [4, 0],
        [5, 0],
        [6, 0],
        [7, 0],
    ]

    down_ls = [
        [0, 7],
        [1, 7],
        [2, 7],
        [3, 7],
        [4, 7],
        [5, 7],
        [6, 7],
        [7, 7],
    ]

    ls_manager = [up_ls, down_ls, left_ls, right_ls]

    danger = [
        [1, 0],
        [1, 1],
        [0, 1],

        [6, 0],
        [7, 1],
        [6, 1],

        [7, 6],
        [6, 6],
        [6, 7],

        [1, 7],
        [0, 6],
        [1, 6]
    ]

    list_first = [
        [0, 0],
        [7, 0],
        [7, 7],
        [0, 7]
    ]

    del_ls = []
    for i in range(4):
        if board[list_first[i][0]][list_first[i][1]] == 1:
            del_ls.append(i)
    for i in del_ls:
        for j in range(i * 3, (i * 3) + 3):
            list_first.append(danger[j])
    del_ls.sort(reverse=True)
    for i in del_ls:
        del danger[(i * 3):((i * 3) + 3)]

    for move in moves:
        if move in danger:
            continue
        elif move in list_first:
            return move, "middle_check!"
        for ls in ls_manager:
            if move in ls:
                tmp_board = copy.deepcopy(board)
                before_execute = for_middle_check(board, ls)
                next_board = Ol.execute(tmp_board, move, player=1, size=8)
                after_execute = for_middle_check(next_board, ls)
                next_moves = Ol.getMoves(next_board, player=-1, size=8)
                if before_execute + 1 < after_execute:
                    frag = 0
                    for next_move in next_moves:
                        if next_move in ls:
                            frag = 1
                    if frag == 1:
                        continue
                    else:
                        return move, "middle_check!"
                elif before_execute + 1 == after_execute:
                    enemy_stone = 0
                    for i in ls:
                        if board[i[1]][i[0]] == -1:
                            enemy_stone += 1
                    if enemy_stone == 0:
                        return move, "middle_check!"

    return open_rate(board, moves)