オセロの盤関係のクラス

オセロの盤関係のクラス。なぜ作ったっていうと、急に作りたくなっただけです。理由はないです。

ちょい修正。なんか間違ってた。2010/08/29
使いやすいように修正。2010/08/31
#coding: utf-8

class Board(object):
WHITE = 0
BLACK = 1
NONE = 2
LENGTH = 8

def __init__(self):
self.initation()

#初期化
def initation(self):
self.board = []
for i in range(Board.LENGTH):
self.board.append([])
for j in range(Board.LENGTH):
self.board[i].append(Board.NONE)

self.board[3][3] = self.board[4][4] = Board.WHITE
self.board[3][4] = self.board[4][3] = Board.BLACK

#駒を置く
def put(self, x, y, color):
tmpBoard = []
for i in range(Board.LENGTH):
tmpBoard.append(range(Board.LENGTH))
self.copyBoard(self.board, tmpBoard)

if self._put(self.board, x, y, color):
return True
else:
self.copyBoard(tmpBoard, self.board)
return False

#駒を置く(内部処理)
def _put(self, board, x, y, color):
if board[x][y] != Board.NONE:
return False

board[x][y] = color
n = self._count(board, color)

for i in [-1, 0, 1]:
for j in [-1, 0, 1]:
self._changeColor(board, x, y, i, j, color)

return self._count(board, color) > n

#再帰的に駒の色を変えていく
def _changeColor(self, board, x, y, dx, dy, color):
x += dx
y += dy
if x < 0 or x >= 8 or y < 0 or y >= 8 or board[x][y] == Board.NONE:
return False

if board[x][y] == color:
return True
else:
if self._changeColor(board, x, y, dx, dy, color):
board[x][y] = color
return True
else:
return False

#colorの手番で駒を置けるかどうかチェックする
def check(self, color):
tmpBoard = []
for i in range(Board.LENGTH):
tmpBoard.append(range(Board.LENGTH))

for i in range(Board.LENGTH):
for j in range(Board.LENGTH):
self.copyBoard(self.board, tmpBoard)
if tmpBoard[i][j] == Board.NONE:
if self._put(tmpBoard, i, j, color):
return True

return False

#aからbに盤をコピーする
def copyBoard(self, a, b):
for i in range(Board.LENGTH):
for j in range(Board.LENGTH):
b[i][j] = a[i][j]


#colorの数を返す
def count(self, color):
return self._count(self.board, color)

#colorの数を返す(内部処理)
def _count(self, board, color):
n = 0

for _b in board:
for __b in _b:
if __b == color:
n += 1

return n

コピーするメソッドみたいのありそうだなーとか思ったりして。あとで調べてみよう。
posted by 右京 | Python

wxPython Frameをマウスのドラッグで動かす

wxFrameをドラッグで動かせるようなプログラムを書いてみたんだけど、実は問題があって、ムチャクチャ速くマウスを動かすとマウスカーソルがFrameから外れて動かなくなるんだよねぇ。
# coding: utf-8
'''
Created on 2010/08/18

@author: ukyo
'''

import wx

class Frame(wx.Frame):
mouseDown = False

def OnMouseDown(self, e):
self.mouseDown = True
self.x = e.GetX()
self.y = e.GetY()

def OnMouseUp(self, e):
self.mouseDown = False

def OnMouseMove(self, e):
if self.mouseDown:
dx = e.GetX() - self.x
dy = e.GetY() - self.y

nextPoint = wx.Point(x=self.GetPosition().x+dx,
y=self.GetPosition().y+dy)

self.SetPosition(nextPoint)
print self.GetPosition()

def OnLeaveWindow(self, e):
self.mouseDown = False

def OnDoubleClick(self, e):
self.Close()

if __name__ == "__main__":
app = wx.App(0)

frame = Frame(None,
-1,
size=(800, 400),
style=wx.MINIMIZE_BOX)

frame.Bind(wx.EVT_LEFT_DOWN, frame.OnMouseDown)
frame.Bind(wx.EVT_LEFT_UP, frame.OnMouseUp)
frame.Bind(wx.EVT_MOTION, frame.OnMouseMove)
frame.Bind(wx.EVT_LEAVE_WINDOW, frame.OnLeaveWindow)
frame.Bind(wx.EVT_LEFT_DCLICK, frame.OnDoubleClick)

app.SetTopWindow(frame)
frame.Center()
frame.Show()
app.MainLoop()
posted by 右京 | Python

tweepyをuserstreamに対応させる

chirpusersteamに対応させるために拡張してみた。filterをちょちょいといじって、hostをchirpstream.twitter.comに書き換えただけなんだけどね。

うお、間違えてた、修正(2010/08/11)。こうかな?
#coding: utf-8

from tweepy.error import TweepError
import tweepy
import simplejson
import urllib

class StreamListener(tweepy.StreamListener):
def on_data(self, data):
json = simplejson.loads(data)
if json.has_key('text'): print json['text']

class Stream(tweepy.Stream):
def userStream(self, follow=None, track=None, async=False):
params = {}
if self.running:
raise TweepError('Stream object already connected!')
self.host = 'chirpstream.twitter.com'
self.url = '/2b/user.json?delimited=length'
if follow:
params['follow'] = ','.join(map(str, follow))
if track:
params['track'] = ','.join(map(str, track))
self.body = urllib.urlencode(params)
self._start(async)

def main():
user = 'your-id'
passwd = 'your-password'
stream = Stream(user, passwd, StreamListener())
stream.userStream()

if __name__ == "__main__":
main()
posted by 右京 | Python

tweepyのStreamingListenerでハマった

tweepyでSteraming APIを試していてハマった。

修正前
import tweepy
import simplejson

class StreamListener(tweepy.StreamListener):
def on_data(self, data):
tweet = simplejson.loads(data)
if tweet.has_key('text'): print tweet['text']


コードはこんな感じで、テキストをダーっと表示しようとしたんだけど、エラーも吐かずに急に止まるので、jsonから直接text部分だけを取り出してprintで表示できるか試してみた。そしたら、cp932じゃダメだって怒られた。というわけで、プログラムの一行目に#coding: utf-8と書いてみると、エラーも無しに動き出した。というか、eclipseの設定をutf-8にしただけじゃ意味ないんだね。

修正後
#coding: utf-8

import tweepy
import simplejson

class StreamListener(tweepy.StreamListener):
def on_data(self, data):
tweet = simplejson.loads(data)
if tweet.has_key('text'): print tweet['text']
posted by 右京 | Python

wxPythonでタイピングゲーム

wxPythonでタイピング。やっぱりゲームを作ってみるとそこそこ慣れるね。

#!/usr/bin/env python

import wx

typingText = (
'WordPress 3.0 has just arrived on the scene - the thirteenth major',
'release of the popular blogging software. It\'s the result of six',
'months of work from a total of 218 different contributors.',
'You can download it now or upgrade from within your WordPress dashboard.',
'What\'s new in 3.0? One of the best ways to find out is to try out',
'the new Twenty Ten theme, which shows off many of the release\'s',
'(which is also called \"Thelonius\") major new features, including',
'custom backgrounds, headers, shortlinks, menus, post types and',
'taxonomies.',
'For those of you laboring on the backend, including developers and',
'sysadmins, you might appreciate that MU and WordPress have finally',
'merged. Now you\'ll be able to run one or multiple blogs from the same',
'installation.',
'Interestingly, the staff of WordPress/Automattic won\'t immediately',
'rush off to start work on WordPress 3.1. Founder Matt Mullenweg said',
'his team will be taking some time to focus on things other than the',
'core product.'
)

class TypingFrame(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(800, 400))

self.index = 0
self.whiteSpace = ''
self.page = 0
self.pageLength = 5

self.font = wx.Font(12, wx.DEFAULT, wx.NORMAL, wx.NORMAL, False, 'Consolas')

self.Bind(wx.EVT_CHAR, self.OnChar)
self.Centre()
self.Show(True)

def Draw(self):
buffer = wx.EmptyBitmap(800, 400)
dc = wx.BufferedDC(wx.ClientDC(self), buffer)
dc.Clear()
dc.SetFont(self.font)

if len(typingText) > self.page+self.pageLength:
end = self.page+self.pageLength
else:
end = len(typingText)

y = 0
lineHeight = self.font.GetPointSize()*1.5
for i in range(self.page,end):
dc.DrawText(typingText[i], 0, y)
y += lineHeight
if i == self.index: dc.DrawText(self.whiteSpace+'^', 0, y)
y += lineHeight

def OnChar(self, event):
if self.index == len(typingText): self.Close()

keycode = event.GetKeyCode()
if keycode == ord(typingText[self.index][len(self.whiteSpace)]):
self.whiteSpace += ' '
if len(self.whiteSpace) == len(typingText[self.index]):
self.index += 1
self.whiteSpace = ''
if self.index%self.pageLength == 0:
self.page += self.pageLength

self.Draw()

class App(wx.App):
def OnInit(self):
frame = TypingFrame(None, -1, 'Typing')
frame.Draw()

self.SetTopWindow(frame)

return True

if __name__ == "__main__":
app = App(0)
app.MainLoop()

posted by 右京 | Python

Google App Engine for Pythonでログイン・ログアウト処理

googleが最初から用意してある例のAPIだと普通に誰でも通しちゃうからね。
#!-*- coding:utf-8 -*-
import cgi
import uuid
import os

from django.utils import simplejson
from google.appengine.ext import db, webapp
from google.appengine.ext.webapp.util import run_wsgi_app

class User(db.Model):
id = db.StringProperty()
password = db.StringProperty()

class Session(db.Model):
user = db.ReferenceProperty(User)
id = db.StringProperty(required = True)
ip = db.StringProperty()

class MainHandler(webapp.RequestHandler):
def get(self):
id = self.request.cookies.get("sessionid","")
if id is None:
id = self.request.get("sessionid")
if id:
session = Session.all().filter("ip",os.environ["REMOTE_ADDR"]).filter("id",id)
if session:
self.response.out.write(
"<html><head></head><body>"+
session[0].user.id+
"<a href='/logout'>logout</a></body></html>")
else :
self.response.out.write(
"""
<html>
<head></head>
<body>
<form method='post' action='/login'>
<input type='text' name='id'></input>
<input type='text' name='password'></input>
<input type='submit' value='submit'></input>
</form>
</body>
</html>
""")

class LoginHandler(webapp.RequestHandler):
def post(self):
users = User.all().filter("id",self.request.get("id")).filter("password",self.request.get("password"))

for user in users:
session = Session(id = str(uuid.uuid4()),user = user,ip = os.environ["REMOTE_ADDR"])
session.put()
self.response.headers.add_header(
"Set-Cookie",
"sessionid=%s; expires=Fri, 31-Dec-2020 23:59:59 GMT" % session.id
)

self.redirect("/")

class LogoutHandler(webapp.RequestHandler):
def get(self):
id = self.request.cookies.get("sessionid","")
sessions = Session.all().filter("id",id)

for session in sessions:
db.delete(session)

self.response.headers.add_header(
"Set-Cookie",
"sessionid=hoge; expires=Fri, 31-Dec-1999 23:59:59 GMT"
)

self.redirect("/")

class UserRegisterHandler(webapp.RequestHandler):
def get(self):
user = User()
user.id = self.request.get("id")
user.password = self.request.get("password")
user.put()

def post(self):
get(self)

application = webapp.WSGIApplication(
[
("/", MainHandler),
("/login", LoginHandler),
("/logout",LogoutHandler),
("/register", UserRegisterHandler)
],
debug = True
)

def main():
run_wsgi_app(application)

if __name__ == "__main__":
main()

ちょっとCookieとSessionの違いがわからないんだけど、まぁ、いいか。
解説すると、まずはMainHandlerが呼び出される。cookieが発行されている場合はユーザ名を表示する。そうでなければ、ログイン画面を表示する。
ユーザ名、パスワードを入れて送信するとLoginHandlerが呼び出される。合ってたらcookie発行。そして、リダイレクト。
ログアウトするには、ユーザ名の隣にあるlogoutとか書いてあるリンクをクリックする。そしたら、LogoutHandlerが呼び出されてsessionとcookieの削除を行う。

セキュリティに関しては、google app engineではapp.yamlにちょっと書き足すだけでhttpsで接続できるから、まぁ、安全なのかな?sessionidもpythonのuuidっていうやつを使えば、それなりに一意性があるsessionidができるらしいから、多分安全(一応、ipもチェックしてるし)。ただ、俺はセキュリティの専門家じゃないんで、これは絶対に安全ですっていうのは言えないんだけどね。

そういや、書いてて思ったことなんだけど、pythonだとコード量が少なくていいね。javaの方はアノテーション、xmlやらが面倒臭すぎるわ。
posted by 右京 | Python
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。