# -*- coding: utf-8 -*-
#===============================================================================
# Copyright (C) 2000-2008, 小泉ひよ子とタマゴ倶楽部
#
# History: Othello Game
# 1988/05, Smalltalk
# 2004/09, Java
# 2005/02, C#
# 2005/03, Jython
# 2008/01, Jython
#===============================================================================
#===============================================================================
# 配列と別れる50の方法
#===============================================================================
from game import *
#===============================================================================
class HexOthelloFrame(DefaultFrame):
def initialize(self):
self.panel = HexOthelloPanel()
def initializeComponent(self):
self.layout = BorderLayout()
self.add(self.panel, BorderLayout.CENTER)
#===============================================================================
class HexOthelloPanel(GameBoardPanel):
dim = 8
black = False
white = not black
_bounds = (-1, -1), (1, -1), (2, 0)
_bounds = list(_bounds)+[(-x, -y) for x, y in _bounds]
def __init__ (self):
GameBoardPanel.__init__(self)
self.mode = self.black
def locateItems(self):
for x, y in self._items():
self.items.append(NullStone(x, y, None))
for x, y, color in (
(6 , 3, self.black),
(9 , 4, self.black),
(6 , 5, self.black),
(10, 3, self.white),
(7 , 4, self.white),
(10, 5, self.white)):
self.place(HexStone(x, y, color))
def _items(self):
s =
for y, points in enumerate((
range(3, 14, 2),
range(2, 15, 2),
range(1, 16, 2),
range(0, 17, 2),
range(1, 16, 2),
range(0, 17, 2),
range(1, 16, 2),
range(2, 15, 2),
range(3, 14, 2))):
s += [(x, y) for x in points]
return s
def prepare(self):
self.__class__.itemExtent = (
self.width/self.dim, self.height/self.dim)
def this_mouseClicked(self, e):
stone = self.detectStone(e)
print ">>> this_mouseClicked: %s"%stone
if stone: return
if stone is nullStone:
print "::: click again ..."
return
self.reversed = False
self.reverse(stone)
if not self.reversed: return
self.place(HexStone(stone.x, stone.y, self.mode))
self.mode = not self.mode
self.repaint()
def detectStone(self, e):
return self.detectPoint(e.x, e.y)
def nullObject(self):
return nullStone
def reverse(self, stone):
for x, y in self._bounds:
e = self.detect(stone.x+x, stone.y+y)
if e.state == (not self.mode):
self.reverseStones(e, x, y)
def detectPoint(self, x, y):
obj = self.nullObject()
for e in self.items:
if e.isExistPoint(x, y): obj = e; break
return obj
def reverseStones(self, stone, x, y):
stones = [stone]
for i in range(1, self.dim):
e = self.detect(stone.x+x*i, stone.y+y*i)
if e.state == None:
stones = ; break
if e.state == self.mode:
break
if e.state == (not self.mode):
stones.append(e)
if not stones: return
for e in stones:
e.state = self.mode
self.reversed = True
print stones
def place(self, stone):
px, py = stone._points()
null = self.detectPoint(px, py)
self.items.remove(null)
self.items.append(stone)
print "place: %s"%stone, "%s,%s"%(px, py)
#===============================================================================
class HexStone(GameItem):
_dx, _dy = 7, 4 # 7*7+4*4=65 <=> 8*8=64
_R2 = (_dx*2)**2
_width, _height = _dx*2, _dy*4
_dw, _dh = _dx*2, _dy*3
deltaX, deltaY = _dw+1, (_dh+1)*2
vertices = [(_dx*x, _dy*y) for x, y in
(1, 0), (2, 1), (2, 3), (1, 4), (0, 3), (0, 1)]
_nPoints = len(vertices)
def __init__(self, x, y, state):
GameItem.__init__(self, x, y)
self.state = state
def __repr__(self):
if self.state == None:
s = self.state
else:
s = ("black", "white")[not self.state]
return "(%s,%s)"%(GameItem.__repr__(self), s)
def __nonzero__(self): return True
def dim(self): return OthelloPanel.dim
def paintBackground(self, g):
width = self.width(g)
height = self.height(g)
x = self.x * width
y = self.y * height
xpoints = [x+dx*2 for dx, dy in self.vertices]
ypoints = [y+dy*2 for dx, dy in self.vertices]
N = self._nPoints
g.color = Color.green
g.fillPolygon(xpoints, ypoints, N)
g.color = Color.black
g.drawPolygon(xpoints, ypoints, N)
def paintItem(self, g):
width = self.width(g)
height = self.height(g)
x = self.x * width
y = self.y * height
color = (Color.black, Color.white)[self.state]
xpoints = [x+dx*2 for dx, dy in self.vertices]
ypoints = [y+dy*2 for dx, dy in self.vertices]
N = self._nPoints
g.color = color
g.fillPolygon(xpoints, ypoints, N)
g.color = Color.black
g.drawPolygon(xpoints, ypoints, N)
#===============================================================================
def width (self, g): return self.deltaX
def height(self, g): return self.deltaY
def isExistPoint(self, x, y):
px, py = self._points()
X, Y = x-px, y-py
return X*X+Y*Y <= self._R2
def _points(self):
x = self.x*self.deltaX+self._width
y = self.y*self.deltaY+self._height
return x, y
class NullStone(HexStone):
def __nonzero__(self): return False
def paintItem(self, g): pass
N = HexOthelloPanel.dim + 1
nullStone = NullStone(None, None, None)
#===============================================================================
def example():
HexOthelloFrame("Othello: hexagon", (270, 262))
#===============================================================================
from _jython2_ import *
signature("-", __file__, '1.0.1')
#===============================================================================