Created
December 8, 2009 03:30
-
-
Save yono/251382 to your computer and use it in GitHub Desktop.
重力付き四目並べをシミュレートする
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding:utf-8 -*- | |
""" | |
connect_four.py | |
重力付き四目並べをシミュレートする | |
""" | |
import random | |
## 戦略を表現 | |
class Plan(object): | |
def __init__(self,name,no): | |
self.name = name | |
self.no = no | |
# 次の手を選ぶ | |
def select(self,column_num): | |
return random.randint(0,column_num-1) | |
## ゲームを表現 | |
class ConnectFour(object): | |
def __init__(self,plan_a,plan_b,row_num=6,column_num=7,connect_num=4): | |
self.BLANK = 0 | |
self.CONNECT_NUM = connect_num | |
self.plan_a = plan_a # 対戦者Aさんのオブジェクト | |
self.plan_b = plan_b # 対戦者Bさんのオブジェクト | |
self.row_num = row_num # 列の数 | |
self.column_num = column_num # 行の数 | |
## 盤面(2次元配列) | |
self.board = [[self.BLANK for i in xrange(0, column_num, 1)] \ | |
for j in xrange(0, row_num, 1)] | |
self.maxround = (row_num * column_num) / 2 | |
## 盤面を出力 | |
def dump_board(self): | |
for row in self.board: | |
print row | |
## ゲームを行う | |
def run(self): | |
round = 0 | |
while True: | |
self._turn(plan_a) | |
if self._win(plan_a): # 勝利判定 | |
print '%s Win!!' % (plan_a.name) | |
break | |
self._turn(plan_b) | |
if self._win(plan_b): # 勝利判定 | |
print '%s Win!!' % (plan_b.name) | |
break | |
round += 1 | |
print "----- finish %d's round -----" % (round) | |
self.dump_board() | |
if self.maxround == round: | |
break | |
print " ------------ final state of board ------------- " | |
self.dump_board() | |
# 盤面に石を置く | |
def _turn(self,plan): | |
while True: | |
selected = plan.select(self.column_num) | |
if self._can_be_putted(selected): | |
self._put(selected,plan) | |
return | |
## 石を置けるかどうか調べる | |
def _can_be_putted(self,position): | |
return (self.board[0][position] == self.BLANK) | |
## 石を置く | |
def _put(self,position,plan): | |
for i in reversed(xrange(len(self.board))): | |
if self.board[i][position] == self.BLANK: | |
self.board[i][position] = plan.no | |
break | |
## 勝利条件を満たしているかどうか調べる | |
def _win(self,plan): | |
## 横の並びを確認 | |
if self._are_connected_in_horizontal(plan): | |
return True | |
## 縦の並びを確認 | |
if self._are_connected_in_vertical(plan): | |
return True | |
## 斜めの並びを確認(右下がり) | |
if self._are_connected_in_skew(plan): | |
return True | |
## 斜めの並びを確認(右上がり) | |
if self._are_connected_in_skew2(plan): | |
return True | |
return False | |
# 特定の方向に石の連結が存在するか | |
def _are_connected(self,plan,step_i,step_j): | |
for i in xrange(len(self.board)): | |
index_i = 0 | |
for j in xrange(len(self.board[i])): | |
index_j = 0 | |
count = 0 | |
while (i+index_i) < len(self.board) and \ | |
(j+index_j) < len(self.board[0]): | |
if self.board[i+index_i][j+index_j] != plan.no: | |
break | |
else: | |
count += 1 | |
index_i += step_i | |
index_j += step_j | |
if count >= self.CONNECT_NUM: | |
return True | |
return False | |
def _are_connected_in_horizontal(self,plan): | |
return self._are_connected(plan,1,0) | |
def _are_connected_in_vertical(self,plan): | |
return self._are_connected(plan,0,1) | |
def _are_connected_in_skew(self,plan): | |
return self._are_connected(plan,1,1) | |
def _are_connected_in_skew2(self,plan): | |
return self._are_connected(plan,-1,1) | |
if __name__=='__main__': | |
plan_a = Plan('planA',1) | |
plan_b = Plan('planB',2) | |
game = ConnectFour(plan_a,plan_b) | |
game.run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment