pythonでコネクトフォー作ってみた PART1 コード

このページでは、「pythonでコネクトフォー作ってみた PART1」のコードが置いてあります。

 

ダウンロードはこちらからどうぞ↓↓↓

プライベートファイル - アクセス禁止
# コマンドプロンプト上でのコネクトフォー
""" CopyRight niwakoma """

import numpy as np
import sys
import random
import copy


class PlayerClass:

    def update_point(self, field, number):
        (x, y) = field.shape
        if((number <= 0) or (y < number)):
            print("Error: number is out of range.(select_point)")
            sys.exit()
        for i in range(len(field)-1, -1, -1):
            point = field[(i, number - 1)]
            if(point == 0):
                return (i, number - 1)
        print("Error: that column in not empty.(select_point)")
        sys.exit()

    def update_field(self, field, xpos, ypos):
        if(field[(xpos, ypos)] != 0):
            print("Error: that point is not 0.(update_field)")
            sys.exit()
        field[xpos, ypos] = PLAYER
        return field

class ComputerClass:

    def choose_number(self, field):
        number_list = []
        transpose_field = np.transpose(field)
        for i in range(len(transpose_field)):
            if(0 in transpose_field[i]):
                number_list.append(i+1)
        r = random.randrange(0, len(number_list))
        return number_list[r]

    def choose_number2_func1(self, field):
        # rowにリーチがかかっているか確認
        point_list = []
        tmp_field = copy.copy(field)
        # -1を削除
        tmp_field[field < 0] = 0
        for i in range(0, len(field)):
            val = 0
            for j in range(0, len(field[0])):
                val = val * tmp_field[(i, j)] + tmp_field[(i, j)]
                tmp_field[(i, j)] = val
                # val == 2
                if((val == 2) and ((j+1) < len(field[0])) and ((j+2) < len(field[0]))):
                    if((field[(i, j+1)] == 0) and (field[(i, j+2)] == 1)):
                        point_list.append((i, j+1))
                if((val == 2) and ((j-2) >= 0) and ((j-3) >= 0)):
                    if((field[(i, j-2)] == 0) and (field[(i, j-3)] == 1)):
                        point_list.append((i, j-2))
                # val == 3
                if((val == 3) and ((j+1) < len(field[0]))):
                    if((field[(i, j+1)] == 0) and ((i, j+1) not in point_list)):
                        point_list.append((i, j+1))
                if((val == 3) and ((j-3) >= 0)):
                    if((field[(i, j-3)] == 0) and ((i, j-3) not in point_list)):
                        point_list.append((i, j-3))
        return point_list

    def choose_number2_func2(self, field):
        # colにリーチがかかっていないか確認
        transpose_field = np.transpose(field)
        point_list = self.choose_number2_func1(transpose_field)
        new_point_list = []
        for i in range(0, len(point_list)):
            v1, v2 = point_list[i]
            new_point_list.append((v2, v1))
        return new_point_list

    def choose_number2(self, field):
        func1_list = self.choose_number2_func1(field)
        func2_list = self.choose_number2_func2(field)
        point_list = list(set(func1_list) | set(func2_list))
        if(len(point_list) != 0):
            number_list = []
            for i in point_list:
                v1, v2 = i
                if((v2+1) not in number_list):
                    number_list.append(v2+1)
            r = random.randrange(0, len(number_list))
            return number_list[r]
        elif(len(point_list) == 0):
            return self.choose_number(field)
        else:
            print("Error: choose_number2")
            sys.exit()

    def update_point(self, field, number):
        (x, y) = field.shape
        if((number <= 0) or (y < number)):
            print("Error: number is out of range.(select_point)")
            sys.exit()
        for i in range(len(field)-1, -1, -1):
            point = field[(i, number - 1)]
            if(point == 0):
                return (i, number - 1)
        print("Error: that column in not empty.(select_point)")
        sys.exit()

    def update_field(self, field, xpos, ypos):
        if(field[(xpos, ypos)] != 0):
            print("Error: that point is not 0.(update_field)")
            sys.exit()
        field[xpos, ypos] = COMPUTER
        return field

class VictoryCondition:
    # 勝利条件
    def victory_condition_row(self, field):
        tmp_field_player = copy.copy(field)
        tmp_field_computer = copy.copy(field)
        # -1を排除
        tmp_field_player[field < 0] = 0
        # 1を排除
        tmp_field_computer[field > 0] = 0
        for i in range(len(field[:,0])):
            val_p = 0
            val_c = 0
            for j in range(len(field[0])):
                val_p = val_p * tmp_field_player[(i, j)] + tmp_field_player[(i, j)]
                val_c = val_c * np.absolute(tmp_field_computer[(i, j)]) + tmp_field_computer[(i, j)]
                tmp_field_player[(i, j)] = val_p
                tmp_field_computer[(i, j)] = val_c
        # 4が含まれているか
        boolean_value_player = False
        count = 0
        while((boolean_value_player == False) and (count < len(field))):
            boolean_value_player = 4 in tmp_field_player[count]
            count += 1
        # -4が含まれているか
        boolean_value_computer = False
        count = 0
        while((boolean_value_computer == False) and (count < len(field))):
            boolean_value_computer = -4 in tmp_field_computer[count]
            count += 1
        return boolean_value_player, boolean_value_computer

    def victory_condition_col(self, field):
        transpose_field = np.transpose(field)
        #print(transpose_field)
        bvp, bvc = self.victory_condition_row(transpose_field)
        return bvp, bvc

    def victory_condition_slash(self, field):
        shift_field = np.zeros(field.shape, dtype=int)
        for i in range(len(shift_field)):
            shift_field[i] = np.roll(field[i], -i)
        bvp, bvc = self.victory_condition_col(shift_field)
        return bvp, bvc

    def victory_condition_backslash(self, field):
        shift_field = np.zeros(field.shape, dtype=int)
        for i in range(len(shift_field)):
            shift_field[i] = np.roll(field[i], i)
        bvp, bvc = self.victory_condition_col(shift_field)
        return bvp, bvc

    def victory_condition(self, field):
        result_player = False
        result_computer = False
        vcr_player, vcr_computer = self.victory_condition_row(field)
        vcc_player, vcc_computer = self.victory_condition_col(field)
        vcs_player, vcs_computer = self.victory_condition_slash(field)
        vcb_palyer, vcb_computer = self.victory_condition_backslash(field)
        if(vcr_player or vcc_player or vcs_player or vcb_palyer):
            result_player = True
            print("You won.")
        if(vcr_computer or vcc_computer or vcs_computer or vcb_computer):
            result_computer = True
            print("Computer won.")
        return result_player, result_computer


class DisplayOutput(VictoryCondition):

    def opening(self):
        print("")
        print("CONNECT FOUR.")
        print("")
        print("Please select first or second.")
        print("First is f.")
        print("Second is s.")
        f_or_s = input()
        if((f_or_s == "f") and (f_or_s != "s")):
            return 1
        elif((f_or_s != "f") and (f_or_s == "s")):
            return -1
        else:
            print("Error: You didn't select f or s.")
            sys.exit()

    def ending(self):
        print("")
        print("Continue?")
        print("y/n")
        yes_or_no = input()
        if(yes_or_no == "n"):
            print("")
            print("END.")
            print("See you next time.")
            sys.exit()
        elif(yes_or_no == "y"):
            print("continue.")
            pass
        if((yes_or_no != "y") and (yes_or_no != "n")):
            print("Error: You didn't select y or n.")
            sys.exit()

    def output_field(self, field):
        print("+--+--+--+--+--+--+--+")
        print("|1|2|3|4|5|6|7|")
        print("+--+--+--+--+--+--+--+")
        for i in range(0, len(field)):
            print("+--+--+--+--+--+--+--+")
            for j in range(0, len(field[0])):
                if(field[(i, j)] == 1):
                    s = "○"
                elif(field[(i, j)] == -1):
                    s = "×"
                else:
                    s = " "
                print("|{0}".format(s), end="")
            print("|")
        print("+--+--+--+--+--+--+--+")



    def initialization(self):
        field = np.zeros((6, 7), dtype=int)
        self.output_field(field)
        print("")
        result_player, result_computer = self.victory_condition(field)
        return field, result_player, result_computer


def main():
    # (行 * 列) = (6 * 7)
    global FIELD
    """
    FIELD = np.array([[0, 0, 0, 0, 0, 0, 0],
                      [0, 0, 0, 0, 0, 0, 0],
                      [0, 0, 0, 0, 0, 0, 0],
                      [0, 0, 0, 0, 0, 0, 0],
                      [0, 0, 0, 0, 0, 0, 0],
                      [0, 0, 0, 0, 0, 0, 0]])
    print(FIELD)
    print("")
    """

    global EMPTY
    EMPTY = 0       # マスが空の状態
    global PLAYER
    PLAYER = 1      # マスに自分の駒がある状態
    global COMPUTER
    COMPUTER = -1   # マスに相手の駒がある状態
    global TURN
    TURN = 0        # 現在、どちらの手番か示す

    pc = PlayerClass()      # Object Player
    cc = ComputerClass()    # Object Computer
    do = DisplayOutput()    # Object Display output


    while(True):
        TURN = do.opening()
        FIELD, result_player, result_computer = do.initialization()
        while((result_player == False) and (result_computer == False)):
            if(TURN == PLAYER):
                # Player turn.
                print("Your turn.")
                print("Please select number from 1 to {0}".format(len(FIELD[0])))
                select_number = input("Select number: ")
                point = pc.update_point(FIELD, int(select_number))
                FIELD = pc.update_field(FIELD, *point)
                TURN = COMPUTER
            elif(TURN == COMPUTER):
                # Computer turn.
                print("Computer turn.")
                print("Please select number from 1 to {0}".format(len(FIELD[0])))
                select_number = cc.choose_number2(FIELD)
                print("Select number: {0}".format(select_number))
                point = cc.update_point(FIELD, select_number)
                FIELD = cc.update_field(FIELD, *point)
                TURN = PLAYER
            else:
                print("Error: TURN")
                sys.exit()
            do.output_field(FIELD)
            print("")
            result_player, result_computer = do.victory_condition(FIELD)
        # Inside while end
        do.ending()
    # Outside while end



if __name__ == '__main__':
    main()

スポンサードサーチ