python爬虫基本告一段落,琢磨搞点其他的,正好在网上看到一个帖子,一个外国13岁小朋友用python写的下棋程序,内容详细,也有意思,拿来练手。
13岁啊。。 我这年纪还在敲 dir啥的吧
想到原先玩跑跑卡丁车时看到欧酷有个4岁熊孩子玩的完美漂移录像,深受打击,从此退出车坛。。。
废话不多说,记录一下这几天的游戏编程折腾史
游戏规则:6*6的方格棋盘,两个人轮流点击棋盘画横线或竖线,谁成功围成一个格子,这个格子算作此人的积分。
游戏架构:客户端和服务端。
先来看下游戏准备工作,需要用到pygame这个python包。
下载小朋友准备的resource文件,游戏用到的图片、声音啥的。
一下为boxgame(客户端)和server代码,已添加注释。
boxes.py
1 import pygame
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
|
import math
from podsixnet.connection import connectionlistener,connection
from time import sleep
# 客户端游戏类
class boxesgame(connectionlistener):
def initsound( self ):
pygame.mixer.music.load( "music.wav" )
self .winsound = pygame.mixer.sound( 'win.wav' )
self .losesound = pygame.mixer.sound( 'lose.wav' )
self .placesound = pygame.mixer.sound( 'place.wav' )
pygame.mixer.music.play()
# 收到来自server的 action:close指令后调用下面方法
def network_close( self ,data):
exit()
def network_yourturn( self ,data):
self .turn = data[ 'torf' ]
def network_startgame( self ,data):
self .running = true
self .num = data[ "player" ]
self .gameid = data[ "gameid" ]
def network_place( self ,data):
self .placesound.play()
x = data[ "x" ]
y = data[ "y" ]
hv = data[ "is_horizontal" ]
if hv:
self .boardh[y][x] = true
else :
self .boardv[y][x] = true
# 设定某个格子为自己的
def network_win( self ,data):
self .owner[data[ "x" ]][data[ "y" ]] = "win"
self .boardh[data[ "y" ]][data[ "x" ]] = true
self .boardv[data[ "y" ]][data[ "x" ]] = true
self .boardh[data[ "y" ] + 1 ][data[ "x" ]] = true
self .boardv[data[ "y" ]][data[ "x" ] + 1 ] = true
self .winsound.play()
self .me + = 1
def network_lose( self ,data):
self .owner[data[ "x" ]][data[ "y" ]] = "lose"
self .boardh[data[ "y" ]][data[ "x" ]] = true
self .boardv[data[ "y" ]][data[ "x" ]] = true
self .boardh[data[ "y" ] + 1 ][data[ "x" ]] = true
self .boardv[data[ "y" ]][data[ "x" ] + 1 ] = true
self .losesound.play()
self .otherplayer + = 1
def __init__( self ):
self .justplaced = 10
pygame.init()
pygame.font.init()
width, height = 389 , 489
self .me = 0
self .otherplayer = 0
self .didwin = false
self .gameid = none
self .num = none
self .num = 0
self .screen = pygame.display.set_mode((width, height))
self .owner = [[ 0 for x in range ( 6 )] for y in range ( 6 )]
self .clock = pygame.time.clock()
self .turn = true
self .running = false
self .boardh = [[false for x in range ( 6 )] for y in range ( 7 )]
self .boardv = [[false for x in range ( 7 )] for y in range ( 6 )]
print ( self .boardh)
print ( self .boardv)
self .initgraphics()
self .initsound()
self .drawhud()
pygame.display.set_caption( "boxes" )
# address=raw_input("host:port(localhost:8080):")
# try:
# if not address:
# host,port="localhost",3721
# else:
# host,port=address.split(":")
# self.connect((host,port))
# except:
# print("error connecting to server")
# print("usage: host:port")
# print("eg 127.0.0.1;3721")
# exit()
self .connect()
print ( "boxes client started" )
while not self .running:
self .pump()
connection.pump()
self .running = true
sleep( 0.01 )
print ( "not running ,connecting..." )
if self .num = = 0 :
# self.turn=true
self .marker = self .greenplayer
self .othermarker = self .blueplayer
else :
self .turn = false
self .marker = self .blueplayer
self .othermarker = self .greenplayer
def initgraphics( self ):
self .normallinev = pygame.image.load( "normalline.png" )
self .normallineh = pygame.transform.rotate( self .normallinev, - 90 )
self .bar_donev = pygame.image.load( "bar_done.png" )
self .bar_doneh = pygame.transform.rotate( self .bar_donev, - 90 )
self .hoverlinev = pygame.image.load( "hoverline.png" )
self .hoverlineh = pygame.transform.rotate( self .hoverlinev, - 90 )
# self.boardh[5][4]=true
# self.boardv[5][5]=true
self .separators = pygame.image.load( "separators.png" )
self .score_panel = pygame.image.load( "score_panel.png" )
self .redindicator = pygame.image.load( "redindicator.png" )
self .greenindicator = pygame.image.load( "greenindicator.png" )
self .greenplayer = pygame.image.load( "greenplayer.png" )
self .blueplayer = pygame.image.load( "blueplayer.png" )
self .winningscreen = pygame.image.load( "youwin.png" )
self .gameover = pygame.image.load( "gameover.png" )
def drawboard( self ):
for x in range ( 6 ):
for y in range ( 7 ):
if not self .boardh[y][x]:
self .screen.blit( self .normallineh, [(x) * 64 + 5 , (y) * 64 ])
else :
self .screen.blit( self .bar_doneh, [(x) * 64 + 5 , (y) * 64 ])
for x in range ( 7 ):
for y in range ( 6 ):
if not self .boardv[y][x]:
self .screen.blit( self .normallinev, [(x) * 64 , (y) * 64 + 5 ])
else :
self .screen.blit( self .bar_donev, [(x) * 64 , (y) * 64 + 5 ])
def update( self ):
# 判断方格是否已经都有归属
if self .me + self .otherplayer = = 36 :
self .didwin = true if self .me> self .otherplayer else false
return 1
self .justplaced - = 1
# print('pump connect info')
connection.pump()
self .pump()
# print('pump connect info finish')
self .clock.tick( 60 )
self .screen.fill( 0 )
self .drawboard()
self .drawhud()
self .drawownermap()
for event in pygame.event.get():
if event. type = = pygame.quit:
exit()
mouse = pygame.mouse.get_pos()
xpos = int (math.ceil((mouse[ 0 ] - 32 ) / 64.0 ))
ypos = int (math.ceil((mouse[ 1 ] - 32 ) / 64.0 ))
# 判断鼠标位置更接近与那条线
is_horizontal = abs (mouse[ 1 ] - ypos * 64 ) < abs (mouse[ 0 ] - xpos * 64 )
ypos = ypos - 1 if mouse[ 1 ] - ypos * 64 < 0 and not is_horizontal else ypos
xpos = xpos - 1 if mouse[ 0 ] - ypos * 64 < 0 and is_horizontal else xpos
board = self .boardh if is_horizontal else self .boardv
isoutofbounds = false
try :
if not board[ypos][xpos]: self .screen.blit( self .hoverlineh if is_horizontal else self .hoverlinev,
[xpos * 64 + 5 if is_horizontal else xpos * 64 ,
ypos * 64 if is_horizontal else ypos * 64 + 5 ])
except :
isoutofbounds = true
pass
if not isoutofbounds:
alreadyplaced = board[ypos][xpos]
else :
alreadyplaced = false
# 鼠标点击时,发送place信号给自己划线
if pygame.mouse.get_pressed()[ 0 ] and not alreadyplaced and not isoutofbounds and self .turn = = true and self .justplaced< = 10 :
self .justplaced = 10
if is_horizontal:
self .boardh[ypos][xpos] = true
self .send({ "action" : "place" , "x" :xpos, "y" :ypos, "is_horizontal" :is_horizontal, "gameid" : self .gameid, "num" : self .num})
else :
self .boardv[ypos][xpos] = true
self .send({ "action" : "place" , "x" :xpos, "y" :ypos, "is_horizontal" :is_horizontal, "gameid" : self .gameid, "num" : self .num})
pygame.display.flip()
# 画记分区域
def drawhud( self ):
self .screen.blit( self .score_panel, [ 0 , 389 ])
myfont = pygame.font.sysfont(none, 32 )
label = myfont.render( "your turn" , 1 , ( 255 , 255 , 255 ))
self .screen.blit(label, ( 10 , 400 ))
self .screen.blit( self .greenindicator if self .turn else self .redindicator ,( 130 , 395 ))
myfont64 = pygame.font.sysfont(none, 64 )
myfont20 = pygame.font.sysfont(none, 20 )
scoreme = myfont64.render( str ( self .me), 1 , ( 255 , 255 , 255 ))
scoreother = myfont64.render( str ( self .otherplayer), 1 , ( 255 , 255 , 255 ))
scoretextme = myfont20.render( "you" , 1 , ( 255 , 255 , 255 ))
scoretextother = myfont20.render( "other player" , 1 , ( 255 , 255 , 255 ))
self .screen.blit(scoretextme, ( 10 , 425 ))
self .screen.blit(scoreme, ( 10 , 435 ))
self .screen.blit(scoretextother, ( 280 , 425 ))
self .screen.blit(scoreother, ( 280 , 435 ))
# 给占领与被占领格子着色
def drawownermap( self ):
for x in range ( 6 ):
for y in range ( 6 ):
if self .owner[x][y]! = 0 :
if self .owner[x][y] = = "win" :
self .screen.blit( self .marker,(x * 64 + 5 ,y * 64 + 5 ))
if self .owner[x][y] = = "lose" :
self .screen.blit( self .othermarker,(x * 64 + 5 ,y * 64 + 5 ))
# 游戏结束后显示gameover或winning的图案
def finished( self ):
self .screen.blit( self .gameover if not self .didwin else self .winningscreen,( 0 , 0 ))
while 1 :
for event in pygame.event.get():
if event. type = = pygame.quit:
exit()
pygame.display.flip()
bg = boxesgame()
while 1 :
if bg.update() = = 1 :
break
bg.finished()
|
server.py
1 __author__ = 'administrator'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
|
import podsixnet.channel
import podsixnet.server
from time import sleep
# 定义客户端通道,继承podsixnet.channel.channel
class clientchannel(podsixnet.channel.channel):
def network( self ,data):
print data
def network_place( self ,data):
hv = data[ "is_horizontal" ]
x = data[ "x" ]
y = data[ "y" ]
# 客户标号
num = data[ "num" ]
# 本游戏id
self .gameid = data[ "gameid" ]
self ._server.placeline(hv,x,y,data, self .gameid,num)
def close( self ):
self ._server.close( self .gameid)
# 定义游戏服务端
class boxesserver (podsixnet.server.server):
channelclass = clientchannel
def __init__( self , * args, * * kwargs):
podsixnet.server.server.__init__( self , * args, * * kwargs)
self .games = []
self .queue = none
self .currentindex = 0
def connected( self ,channel,addr):
print 'new connection:' ,channel
# 如果队列为空,则新建一局game
if self .queue = = none:
self .currentindex + = 1
channel.gameid = self .currentindex
self .queue = game(channel, self .currentindex)
#如果队列中已有一局game在等待,则将新连进来的channel作为第二名游戏者与等待游戏者配对,加入games[]列表,将queue清空
else :
channel.gameid = self .currentindex
self .queue.player1 = channel
self .queue.player0.send({ "action" : "startgame" , "player" : 0 , "gameid" : self .queue.gameid})
self .queue.player1.send({ "action" : "startgame" , "player" : 1 , "gameid" : self .queue.gameid})
self .games.append( self .queue)
self .queue = none
# def placeline(self,is_h,x,y,data,gameid,num):
# if num==self.turn:
# self.turn=0 if self.turn else 1
# self.player1.send({"action":"yourturn","torf":true if self.turn==1 else false})
# self.player0.send({"action":"yourturn","torf":true if self.turn==0 else false})
# if is_h:
# self.boardh[y][x]=true
# else:
# self.boardv[y][x]=true
# self.player0.send(data)
# self.player1.send(data)
#通知gameserver哪句游戏要划线,调用游戏placeline
def placeline( self ,is_h,x,y,data,gameid,num):
game = [a for a in self .games if gameid = = a.gameid]
if len (game) = = 1 :
game[ 0 ].placeline(is_h,x,y,data,num)
# 关闭某局game
def close( self ,gameid):
try :
game = [a for a in self .games if a.gameid = = gameid][ 0 ]
game.player0.send({ "action" : "close" })
game.player1.send({ "action" : "close" })
except :
pass
# 判断方格归属
def tick( self ):
index = 0
# 状态未改变 code 3
change = 3
# 扫描每局游戏
for game in self .games:
change = 3
# 扫描2次,因为存在放置一个线条完成两个方格占领的情况
for time in range ( 2 ):
for y in range ( 6 ):
for x in range ( 6 ):
# 判断是否是新围成的方格
if game.boardh[y][x] and game.boardv[y][x] and game.boardh[y + 1 ][x] and game.boardv[y][x + 1 ] and not game.owner[x][y]:
# 是否为己方围成的,围成的一方可以继续走一步
# 此处self.games[index]能否替换为game?
if self .games[index].turn = = 0 :
self .games[index].owner[x][y] = 2
game.player1.send({ "action" : "win" , "x" :x, "y" :y})
game.player0.send({ "action" : "lose" , "x" :x, "y" :y})
change = 1
print ( "player1 win 1 grid" )
else :
self .games[index].owner[x][y] = 1
game.player0.send({ "action" : "win" , "x" :x, "y" :y})
game.player1.send({ "action" : "lose" , "x" :x, "y" :y})
change = 0
print ( "player0 win 1 grid" )
# 如果状态改变了(即有一方完成了方格占领)则下一步仍由该方走棋;否则正常交替走棋
self .games[index].turn = change if change! = 3 else self .games[index].turn
game.player1.send({ "action" : "yourturn" , "torf" :true if self .games[index].turn = = 1 else false})
game.player0.send({ "action" : "yourturn" , "torf" :true if self .games[index].turn = = 0 else false})
index + = 1
self .pump()
# 单纯一局游戏的控制类
class game:
def __init__( self ,player0,currentindex):
self .turn = 0
self .owner = [[false for x in range ( 6 )] for y in range ( 6 )]
self .boardh = [[false for x in range ( 6 )] for y in range ( 7 )]
self .boardv = [[false for x in range ( 7 )] for y in range ( 6 )]
self .player0 = player0
self .player1 = none
self .gameid = currentindex
# while not self.running:
# self.pump()
# connection.pump()
# sleep(0.01)
# if self.num==0:
# self.turn=true
# self.marker=self.greenplayer
# self.othermarker=self.blueplayer
# else:
# self.turn=false
# self.marker=self.blueplayer
# self.othermarker=self.greenplayer
# 划线
def placeline( self ,is_h,x,y,data,num):
if num = = self .turn:
self .turn = 0 if self .turn else 1
self .player1.send({ "action" : "yourturn" , "torf" :true if self .turn = = 1 else false})
self .player0.send({ "action" : "yourturn" , "torf" :true if self .turn = = 0 else false})
if is_h:
self .boardh[y][x] = true
else :
self .boardv[y][x] = true
self .player0.send(data)
self .player1.send(data)
# def network_palce(self,data):
# x=data["x"]
# y=data["y"]
# hv=data["is_horizontal"]
# if hv:
# self.boardh[y][x]=true
# else:
# self.boardv[y][x]=true
print "staring server on localhost"
address = raw_input ( "host:port(localhost:8080):" )
if not address:
host,port = "localhost" , 31425
print ( "default host and port" )
print (host, ":" ,port)
else :
host,port = address.split( ":" )
print (host, ":" ,port)
boxesserver = boxesserver( localaddr = ( "127.0.0.1" , 31425 ))
# boxesserver=boxesserver()
while true:
boxesserver.pump()
boxesserver.tick()
sleep( 0.01 ) 就是这样,休息,休息一下。
|
以上就是本次介绍的儿童学习python游戏编程的全部知识点内容,感谢大家对服务器之家的支持。