かめよこある記

~カメもタワシも~
To you who want to borrow the legs of a turtle

〇×ゲーム ~2020夏~

2020-08-07 21:46:26 | もしもゲームがつくれたなら

【プロジェクト〇×】
 Pythonで、簡単なものなら何かつくれるかもしれない。
 「〇×ゲーム」に白羽の矢が立った。
 はじめ、思いつくままに組んだ思考ルーチンは、とにかく弱かった。
 必勝パターンに持ち込まれるとCPUは必ず負けた。
 双方が頑張れば必ず引き分けになるといわれるこのゲームで、何かがおかしかった。
 梅雨が明け、厳しい暑さの続く2020年の夏、試行錯誤が続いた。
 そして、ついに負けなくなった。
 ただ、引き分けばかりで面白くなかった・・・。

【遊び方】
 CPUと対戦する〇×ゲームです。
 毎回、先攻後攻がランダムで決まります。
 必ず先攻が〇、後攻が×です。
 マウスで操作し、空いているマスをクリックしてください。
 終了して、しばらく待つかクリックすると再びゲームがはじまります。
 ※マス内を強くクリックすると、そのまま駒が置かれることがあるので注意してください。
 たまに、CPUがうっかりミスをすることがあります。

【リスト】 ※インデントの間隔に注意してください。

# 〇×ゲーム 2020夏 by kameyoko

import tkinter
import random

# 変数、リストの設定
fnt = ["Times New Roman",12] 
sym = ["先手:〇", "後手:X"]
score =[ 0, 0, 0]

board = []
for i in range(3):
    board.append([0]*3)

ms_x = 0
ms_y = 0
ms_c = 0

# マウス関係
def ms_move(e):
    global ms_x, ms_y
    ms_x = e.x
    ms_y = e.y

def ms_click(e):
    global ms_c
    ms_c = 1

def ms_release(e):
    global ms_c
    ms_c = 0

def board_init(): # 盤の初期化と描画
    global timer, count, player
    timer = 0
    count = 0
    player = random.randint(0,1)
    for y in range(0,3):
        for x in range(0, 3):
            board[y][x] = 0
    cvas.delete("GR", "TX2")
    for i in range(1,3):
        cvas.create_line( 40+i*80, 40, 40+i*80, 280, fill="black", width=5, tag="GR")
        cvas.create_line( 40, 40+i*80, 280, 40+i*80, fill="black", width=5, tag="GR")
    display_letter(160, 300, "あなたは" + sym[player] + "です","TX1")

def draw_graph(x,y,p): # 駒の描画
    if p == 0: cvas.create_oval(x+20, y+20, x+60, y+60, fill="white", outline="black", width=3, tag="GR")
    else :
        cvas.create_line(x+20, y+20, x+60, y+60, fill="black",width=3, tag="GR")
        cvas.create_line(x+60, y+20, x+20, y+60, fill="black",width=3, tag="GR")
    cvas.update()

def put_piece( y, x): # 駒を置く
    global count, turn
    gx = 40 + x * 80
    gy = 40 + y * 80
    draw_graph(gx,gy, turn)
    board[y][x] = (turn+1)*(turn+1)
    board_check(turn+1)
    count = count + 1
    
def display_letter(x, y, txt,tg): # 文字表示
    cvas.delete(tg)
    cvas.create_text(x, y, text=txt, fill="black", font=fnt, tag=tg)
    cvas.update()

def display_score(): display_letter(160, 340, "{}勝{}敗{}分".format(score[0],score[1],score[2]), "TX3") # スコア表示          

def board_check(e): # 盤のチェック
    global timer, turn, player, msg
    win = 0
    e = e*e
    a = 0
    b = 0
    for i in range(0, 3):
        a = a + board[i][i]
        b = b + board[i][2-i]
        c = 0
        d = 0
        for j in range(0, 3):
            c = c + board[i][j]
            d = d + board[j][i]
        if c==e*3 or d==e*3: win = 1  
    if a == e*3 or b == e*3: win = 1
    if win == 1:
        msg = sym[turn] + " の 勝ちです"
        w = (turn != player)*1
        score[w] = score[w] + 1
        timer = 50

def player_turn(): # プレイヤーの操作
    global ms_x, ms_y, ms_c
    if ms_c == 1:
        if 40 <= ms_y and ms_y < 280 and 40 <= ms_x and ms_x < 280:
            y = int((ms_y-40)/80)
            x = int((ms_x-40)/80)
            if board[y][x] == 0: put_piece(y, x)
            
def think_com(e): # CPUの思考ルーチン
    global turn
    f = (e ^ 3)
    e = e*e
    f = f*f
    point=-1
    ay = 0
    ax = 0
    r = random.randint(1,5)
    for y in range(0,3):
        for x in range(0,3):
            pt = 0
            q = random.randint(1,3) 
            if board[y][x] ==0:
                a = 0
                b = 0
                for j in range(0,3):
                    # 縦横のチェック
                    a = a + board[y][j]
                    b = b + board[j][x]
                c = (a == e*2)*5+(a == f*2)*4+(a == e)*1
                d = (b == e*2)*5+(b == f*2)*4+(b == e)*1
                if c < 4 and r < 2: c = c + (y+x == 2)*1 + (y==x)*1
                if d < 4 and r < 2: d = d + (y+x == 2)*1 + (y==x)*1                
                if c > pt: pt = c                   
                if d > pt: pt = d
                    
                if y == x: # 斜めチェック1
                    a = 0
                    for i in range(0,3):
                        a = a + board[i][i]
                    c = (a == e*2)*5+(a == f*2)*4+(a == e)*1
                    if c < 4 and r <2: c= c + 1 + (y == 1)*1                   
                    if c > pt: pt = c
                        
                if  y+x == 2: # 斜めチェック2                  
                    b = 0
                    for i in range(0,3):
                        b = b + board[i][2-i]
                    d = (b == e*2)*5+(b == f*2)*4+(b == e)*1
                    if d < 4 and r < 2: d = d + 1 + (y == 1)*1                  
                    if d > pt: pt = d

                if pt > point: # 優先順位の比較
                    ay = y
                    ax = x
                    point = pt
                elif pt == point and q<3:
                    ay = y
                    ax = x
                    
    put_piece(ay, ax)                                  
        
def main_loop(): # メイン処理
    global timer, count, turn, player, msg
    if timer == 0:
        
        if count < 9:
            turn = count%2
            
            if turn == player: player_turn()                                                          
            else: think_com(turn+1)        
                
        else:
            msg = "引き分けです"
            score[2] = score[2] + 1
            timer = 50
                        
    else:
        timer = timer - 1
        if timer == 49:
            display_letter(160, 320, msg, "TX2")
            display_score()
        elif timer ==0 or ms_c == 1: board_init()
            
    root.after(100, main_loop)       

# 初期設定       
root = tkinter.Tk()
root.title("〇Xゲーム")
root.resizable(False, False)
root.bind("<Motion>", ms_move)
root.bind("<ButtonPress>", ms_click)
root.bind("<ButtonRelease>", ms_release)
cvas = tkinter.Canvas(root, width=320, height=360,bg="white")
cvas.pack()
board_init()
main_loop()
cvas.mainloop()


ゲーム制作ランキング


コメント    この記事についてブログを書く
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする
« 一瞬だけ1位じゃダメですか? | トップ | 忍びよる影との戦い »
最新の画像もっと見る

コメントを投稿

もしもゲームがつくれたなら」カテゴリの最新記事