オセロを作る(3)

少し進んだ。

  • 今日の改良点
    • 挟んだコマの色を反転させるようにした。
    • 8方向それぞれで関数を定義。
    • 初期設定部分をdef main()の外へ出す。
  • 使用方法
    • ファイルMiniOthello.pywを実行。
    • 変数TNUMの数で一辺の升数を決めている。一般の升は8x8らしい。大きくとれば大きな盤になる。
    • コマを置きたい場所にマウスをもっていきクリックする。
    • クリックする毎に黒と白のコマが交互に置かれる。
    • 終了する場合はEscキーを押す。
  • 今後の改良予定
    • コマを置いてはいけない場所には置けないようにする(現在はどこでも置ける)。
    • 終了時に勝敗の判定を行う。

MiniOthello.pywは以下の通り。

#!/bin/env python
# coding: utf-8
# ------------------------------------------------------------------
# Mini Othello  ver.0.3 (MiniOthello.pyw)
#                           2008/11/05
import pygame
import sys
from pygame.locals import *

WDTH = 50  # 盤上に並べるタイルの幅
TNUM = 8   # 一辺のタイルの数:総数はTNUM*TNUMになる

SCR_W = WDTH * TNUM # ウィンドウの大きさ(幅)
SCR_H = WDTH * TNUM # ウィンドウの大きさ(縦)
WPOS = WDTH*(TNUM-1)

""" 初期設定 """
pygame.init()
screen = pygame.display.set_mode( (SCR_W, SCR_H) )
image1 = pygame.image.load('tile.bmp')
image2 = pygame.image.load('black.bmp')
image3 = pygame.image.load('white.bmp')
image1 = image1.convert()
image2 = image2.convert()
image3 = image3.convert()
ckey2 = image2.get_at((0,0))
ckey3 = image3.get_at((0,0))
image2.set_colorkey(ckey2)
image3.set_colorkey(ckey3)
imagerect1 = image1.get_rect()
imagerect2 = image2.get_rect()
imagerect3 = image3.get_rect()

""" コマの色を記録する変数を定義
komacolor=0 : コマは置かれていない
      =1 : 黒コマ
         =2 : 白コマ        
"""
komacolor = [[0 for x in range(TNUM)] for x in range(TNUM)]

global rnum

def flipkomaN1(x, y, rnum):
    """ 白コマを反転させる(north方向)"""
    if komacolor[x][y-1] == 2 and y >= 2:
        if komacolor[x][y-2] == 0: return
        if komacolor[x][y-2] == 1:
            for i in range(rnum+1):
                screen.blit(image2,
                            imagerect2.move(WDTH*x,WDTH*(y-1+i)))
                komacolor[x][y-1+i] = 1
            return
        else:
            rnum +=1
            flipkomaN1(x,y-1, rnum)
    return
        
def flipkomaN2(x, y, rnum):
    """ 黒コマを反転させる(north方向)"""
    if komacolor[x][y-1] == 1 and y >= 2:
        if komacolor[x][y-2] == 0: return
        if komacolor[x][y-2] == 2:
            for i in range(rnum+1):
                screen.blit(image3,
                            imagerect3.move(WDTH*x,WDTH*(y-1+i)))
                komacolor[x][y-1+i] = 2
            return
        else:
            rnum +=1
            flipkomaN2(x,y-1, rnum)
    return

def flipkomaS1(x, y, rnum):
    """ 白コマを反転させる(south方向)"""
    if y <= TNUM-3 and komacolor[x][y+1] == 2:
        if komacolor[x][y+2] == 0: return
        if komacolor[x][y+2] == 1:
            for i in range(rnum+1):
                screen.blit(image2,
                            imagerect2.move(WDTH*x,WDTH*(y+1-i)))
                komacolor[x][y+1-i] = 1
            return
        else:
            rnum +=1
            flipkomaS1(x,y+1, rnum)
    return

def flipkomaS2(x, y, rnum):
    """ 黒コマを反転させる(south方向)"""
    if y <= TNUM-3 and komacolor[x][y+1] == 1:
        if komacolor[x][y+2] == 0: return
        if komacolor[x][y+2] == 2:
            for i in range(rnum+1):
                screen.blit(image3,
                            imagerect3.move(WDTH*x,WDTH*(y+1-i)))
                komacolor[x][y+1-i] = 2
            return
        else:
            rnum +=1
            flipkomaS2(x,y+1, rnum)
    return

def flipkomaW1(x, y, rnum):
    """ 白コマを反転させる(west方向)"""
    if komacolor[x-1][y] == 2 and x >= 2:
        if komacolor[x-2][y] == 0: return
        if komacolor[x-2][y] == 1:
            for i in range(rnum+1):
                screen.blit(image2,
                            imagerect2.move(WDTH*(x-1+i),WDTH*y))
                komacolor[x-1+i][y] = 1
            return
        else:
            rnum +=1
            flipkomaW1(x-1,y, rnum)
    return
        
def flipkomaW2(x, y, rnum):
    """ 黒コマを反転させる(west方向)"""
    if komacolor[x-1][y] == 1 and x >= 2:
        if komacolor[x-2][y] == 0: return
        if komacolor[x-2][y] == 2:
            for i in range(rnum+1):
                screen.blit(image3,
                            imagerect3.move(WDTH*(x-1+i),WDTH*y))
                komacolor[x-1+i][y] = 2
            return
        else:
            rnum +=1
            flipkomaW2(x-1,y, rnum)
    return

def flipkomaE1(x, y, rnum):
    """ 白コマを反転させる(east方向)"""
    if x <= TNUM-3 and komacolor[x+1][y] == 2:
        if komacolor[x+2][y] == 0: return
        if komacolor[x+2][y] == 1:
            for i in range(rnum+1):
                screen.blit(image2,
                            imagerect2.move(WDTH*(x+1-i),WDTH*y))
                komacolor[x+1-i][y] = 1
            return
        else:
            rnum +=1
            flipkomaE1(x+1,y, rnum)
    return

def flipkomaE2(x, y, rnum):
    """ 黒コマを反転させる(east方向)"""
    if x <= TNUM-3 and komacolor[x+1][y] == 1:
        if komacolor[x+2][y] == 0: return
        if komacolor[x+2][y] == 2:
            for i in range(rnum+1):
                screen.blit(image3,
                            imagerect3.move(WDTH*(x+1-i),WDTH*y))
                komacolor[x+1-i][y] = 2
            return
        else:
            rnum +=1
            flipkomaE2(x+1,y, rnum)
    return

def flipkomaNW1(x, y, rnum):
    """ 白コマを反転させる(north-west方向)"""
    if komacolor[x-1][y-1] == 2 and y >= 2 and x >= 2:
        if komacolor[x-2][y-2] == 0: return
        if komacolor[x-2][y-2] == 1:
            for i in range(rnum+1):
                screen.blit(image2,
                            imagerect2.move(WDTH*(x-1+i),WDTH*(y-1+i)))
                komacolor[x-1+i][y-1+i] = 1
            return
        else:
            rnum +=1
            flipkomaNW1(x-1,y-1, rnum)
    return
        
def flipkomaNW2(x, y, rnum):
    """ 黒コマを反転させる(north-west方向)"""
    if komacolor[x-1][y-1] == 1 and y >= 2 and x >= 2:
        if komacolor[x-2][y-2] == 0: return
        if komacolor[x-2][y-2] == 2:
            for i in range(rnum+1):
                screen.blit(image3,
                            imagerect3.move(WDTH*(x-1+i),WDTH*(y-1+i)))
                komacolor[x-1+i][y-1+i] = 2
            return
        else:
            rnum +=1
            flipkomaNW2(x-1,y-1, rnum)
    return

def flipkomaSE1(x, y, rnum):
    """ 白コマを反転させる(south-east方向)"""
    if x <= TNUM-3 and y <= TNUM-3 and komacolor[x+1][y+1] == 2:
        if komacolor[x+2][y+2] == 0: return
        if komacolor[x+2][y+2] == 1:
            for i in range(rnum+1):
                screen.blit(image2,
                            imagerect2.move(WDTH*(x+1-i),WDTH*(y+1-i)))
                komacolor[x+1-i][y+1-i] = 1
            return
        else:
            rnum +=1
            flipkomaSE1(x+1,y+1, rnum)
    return

def flipkomaSE2(x, y, rnum):
    """ 黒コマを反転させる(south-east方向)"""
    if x <= TNUM-3 and y <= TNUM-3 and komacolor[x+1][y+1] == 1:
        if komacolor[x+2][y+2] == 0: return
        if komacolor[x+2][y+2] == 2:
            for i in range(rnum+1):
                screen.blit(image3,
                            imagerect3.move(WDTH*(x+1-i),WDTH*(y+1-i)))
                komacolor[x+1-i][y+1-i] = 2
            return
        else:
            rnum +=1
            flipkomaSE2(x+1,y+1, rnum)
    return

def flipkomaSW1(x, y, rnum):
    """ 白コマを反転させる(south-west方向)"""
    if y <= TNUM-3 and x >= 2 and komacolor[x-1][y+1] == 2:
        if komacolor[x-2][y+2] == 0: return
        if komacolor[x-2][y+2] == 1:
            for i in range(rnum+1):
                screen.blit(image2,
                            imagerect2.move(WDTH*(x-1+i),WDTH*(y+1-i)))
                komacolor[x-1+i][y+1-i] = 1
            return
        else:
            rnum +=1
            flipkomaSW1(x-1,y+1, rnum)
    return

def flipkomaSW2(x, y, rnum):
    """ 黒コマを反転させる(south-west方向)"""
    if y <= TNUM-3 and x >= 2 and komacolor[x-1][y+1] == 1:
        if komacolor[x-2][y+2] == 0: return
        if komacolor[x-2][y+2] == 2:
            for i in range(rnum+1):
                screen.blit(image3,
                            imagerect3.move(WDTH*(x-1+i),WDTH*(y+1-i)))
                komacolor[x-1+i][y+1-i] = 2
            return
        else:
            rnum +=1
            flipkomaSW2(x-1,y+1, rnum)
    return

def flipkomaNE1(x, y, rnum):
    """ 白コマを反転させる(north-east方向)"""
    if x <= TNUM-3 and y >= 2 and komacolor[x+1][y-1] == 2:
        if komacolor[x+2][y-2] == 0: return
        if komacolor[x+2][y-2] == 1:
            for i in range(rnum+1):
                screen.blit(image2,
                            imagerect2.move(WDTH*(x+1-i),WDTH*(y-1+i)))
                komacolor[x+1-i][y-1+i] = 1
            return
        else:
            rnum +=1
            flipkomaNE1(x+1,y-1, rnum)
    return

def flipkomaNE2(x, y, rnum):
    """ 黒コマを反転させる(north-east方向)"""
    if x <= TNUM-3 and y >= 2 and komacolor[x+1][y-1] == 1:
        if komacolor[x+2][y-2] == 0: return
        if komacolor[x+2][y-2] == 2:
            for i in range(rnum+1):
                screen.blit(image3,
                            imagerect3.move(WDTH*(x+1-i),WDTH*(y-1+i)))
                komacolor[x+1-i][y-1+i] = 2
            return
        else:
            rnum +=1
            flipkomaNE2(x+1,y-1, rnum)
    return


def main():
    screen.fill((0,0,0))
    pygame.display.set_caption('Mini Othello')

    pygame.mouse.set_visible(True)
    whoturn = 0    # どちらの順番かを記録しておく変数

    """ 初期画面を描画 """
    for i in xrange(0, WPOS+1, WDTH):
        for j in xrange(0, WPOS+1, WDTH):
            screen.blit(image1, imagerect1.move(i,j))
    """ 始めから置かれている4つのコマ """
    screen.blit(image2, imagerect2.move(WDTH*TNUM/2,WDTH*TNUM/2))
    screen.blit(image2, imagerect2.move(WDTH*(TNUM/2-1),WDTH*(TNUM/2-1)))
    screen.blit(image3, imagerect3.move(WDTH*(TNUM/2-1),WDTH*TNUM/2))
    screen.blit(image3, imagerect3.move(WDTH*TNUM/2,WDTH*(TNUM/2-1)))
    komacolor[TNUM/2][TNUM/2] = 1
    komacolor[TNUM/2-1][TNUM/2-1] = 1
    komacolor[TNUM/2-1][TNUM/2] = 2
    komacolor[TNUM/2][TNUM/2-1] = 2
    pygame.display.flip()

    while 1:
        for event in pygame.event.get():
            if (event.type == KEYDOWN and
                event.key == K_ESCAPE):
                pygame.quit()
                sys.exit()
            if event.type == MOUSEBUTTONDOWN:
                whoturn += 1
                xpos = int(pygame.mouse.get_pos()[0]/WDTH)
                ypos = int(pygame.mouse.get_pos()[1]/WDTH)
                if komacolor[xpos][ypos] == 0:
                    if whoturn%2 == 0:
                        """ 黒コマを置く """
                        screen.blit(image2, imagerect2.move(WDTH*xpos,WDTH*ypos))
                        komacolor[xpos][ypos] = 1
                        """ 挟んだコマを裏返す """
                        flipkomaN1(xpos, ypos, rnum=0)
                        flipkomaS1(xpos, ypos, rnum=0)
                        flipkomaW1(xpos, ypos, rnum=0)
                        flipkomaE1(xpos, ypos, rnum=0)
                        flipkomaNW1(xpos, ypos, rnum=0)
                        flipkomaSE1(xpos, ypos, rnum=0)
                        flipkomaSW1(xpos, ypos, rnum=0)
                        flipkomaNE1(xpos, ypos, rnum=0)
                                    
                    else:
                        """ 白コマを置く """
                        screen.blit(image3, imagerect3.move(WDTH*xpos,WDTH*ypos))
                        komacolor[xpos][ypos] = 2
                        """ 挟んだコマを裏返す """
                        flipkomaN2(xpos, ypos, rnum=0)
                        flipkomaS2(xpos, ypos, rnum=0)
                        flipkomaW2(xpos, ypos, rnum=0)
                        flipkomaE2(xpos, ypos, rnum=0)
                        flipkomaNW2(xpos, ypos, rnum=0)
                        flipkomaSE2(xpos, ypos, rnum=0)
                        flipkomaSW2(xpos, ypos, rnum=0)
                        flipkomaNE2(xpos, ypos, rnum=0)
                        
                pygame.display.flip()

if __name__ == '__main__':
    main()