Skip to content

Instantly share code, notes, and snippets.

@yono
Created December 8, 2009 03:30
Show Gist options
  • Save yono/251382 to your computer and use it in GitHub Desktop.
Save yono/251382 to your computer and use it in GitHub Desktop.
重力付き四目並べをシミュレートする
#!/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