first stable version

This commit is contained in:
Jerry Wu 2018-06-01 18:17:10 +08:00
parent 152a71ff05
commit 4e8525f4cf
5 changed files with 737 additions and 595 deletions

275
card.py
View File

@ -3,6 +3,7 @@ import game
from room import Room
from json import dumps
cards = dict()
card_name = ["1.攻擊","2.防禦","3.治癒","4.補給","5.強奪","6.奇襲","7.交易","8.洞悉","9.妙策","10.掃射","11.加護","12.劇毒","13.詛咒","14.反制","15.狂亂","16.逆轉"]
unattackable = ['2','8','14','17','18']
@ -10,9 +11,14 @@ unrobable = ['8','17','18']
for i in range(len(card_name)):
cards[str(i+1)] = card_name[i] # initialize cards
# create default deck
# 攻擊*15 防禦*15 治癒*15 補給*10 強奪*10 奇襲*10 交易*10 洞悉*5 妙策*5 掃射*5 加護*5 劇毒*2 詛咒*2 反制*2 狂亂*2 逆轉*2
#default_deck = ['1', '2', '3'] * 5 + ['4', '5', '6', '7'] * 3 + ['8', '9', '10', '11'] * 2 + ['12', '13', '14', '15', '16']
default_deck = ['3', '4', '2', '1']*15
"""
攻擊*7 防禦*7 治癒*7
補給*4 強奪*4 奇襲*4 交易*4
洞悉*2 妙策*2 掃射*2 加護*2
劇毒*1 詛咒*1 反制*1 狂亂*1 逆轉*1
"""
default_deck = ['1', '2', '3'] * 7 + ['4', '5', '6', '7'] * 4 + ['8', '9', '10', '11'] * 2 + ['12', '13', '14', '15', '16']
random.shuffle(default_deck) # wash
# card functions
@ -26,11 +32,10 @@ def attack(wscur, wsene):
r = []
cur.damage = 2 # 給反制判斷的
r.append(( (wscur, ), dumps({"msg": "attack", "data": [cur.name, ene.name]})))
r.append(( (wscur, wsene), dumps({"msg": "attack", "data": [cur.name, ene.name]})))
if ene.defence():
r.append(( (wsene, ),
dumps({"msg": "attack", "data": [cur.name, ene.name],
"action": "toDefend", "value": {"damage": cur.damage}})
dumps({"action": "toDefend", "value": {"damage": cur.damage, "type": "attack"}})
))
cur.status = Room.NOTHING
ene.status = Room.DEFENCE
@ -38,7 +43,10 @@ def attack(wscur, wsene):
r.append(( (wsene, wscur),
dumps({"msg": "damaged", "data": [ene.name, cur.damage]})
))
cur.status = Room.NOTHING
ene.life -= cur.damage
r.extend(Room.start_turn(wsene, wscur))
cur.attacking = False
cur.damage = 0 # reset
"""
@ -62,10 +70,10 @@ def defend(wscur,wsene): # cur是用卡方
cur, ene = wscur.player, wsene.player
r = []
if ene.attacking or ene.surprise:
r.append(( (wsene,wscur), "{} 防禦成功".format(cur.name)))
r.append(( (wsene,wscur), dumps({"msg": "defended", "data": [cur.name]})))
else:
r.append(( (wsene,wscur), "{} 沒什麼可以防禦的,回復一點生命".format(cur.name)))
r.append(( (wsene,wscur), dumps({"msg": "defend", "data": [cur.name]})))
cur.life += 1
return r
@ -89,209 +97,206 @@ def supply(wscur,wsene):
def rob(wscur,wsene):
cur, ene = wscur.player, wsene.player
r = []
r.append(( (wscur, ), dumps({"msg": "rob", "data": [cur.name, ene.name],
"action": "toRob", "value": {"enemy_card": ene.hand}})))
cur.robbing = True
print("{} 正在對 {} 行搶".format(cur.name,ene.name))
if ene.keep():
game.display(ene) # 顯示手牌
while True:
choice = input("請問要防禦嗎? 不使用請輸入0 ")
if choice in ene.hand:
if choice in unrobable:
skills[choice](cur,ene)
ene.remove_card(choice)
break
elif choice == "0":
break
else:
if len(ene.hand) == 0:
print("可惜,{} 有夠窮,沒東西能搶".format(ene.name))
else:
game.display(ene)
while True:
swag = input("{} 要搶哪張?".format(cur.name))
if swag in ene.hand:
ene.robbed(swag)
cur.add_card(swag)
break
cur.robbing = False
cur.status = Room.ROBBING
r.append(( (wsene, ), dumps({"msg": "rob", "data": [cur.name, ene.name]})))
return r
def surprise(wscur,wsene):
cur, ene = wscur.player, wsene.player
cur.surprise = True
cur.damage = 1 # 給反制判斷
print("{} 發動奇襲".format(cur.name))
r = []
cur.damage = 1
r.append(( (wscur, wsene), dumps({"msg": "surprise", "data": [cur.name]})))
if ene.defence():
game.display(ene) # 顯示手牌
while True:
choice = input("請問要防禦嗎? 不使用請輸入0 ")
if choice in ene.hand:
if choice in unattackable:
skills[choice](cur,ene)
ene.remove_card(choice)
break
elif choice == "0":
print("{} 受到{}點傷害,而且掉了一張手牌".format(ene.name,cur.damage))
ene.life -= cur.damage
drop = random.choice(ene.hand)
ene.remove_card(drop)
break
r.append(( (wsene, ),
dumps({"action": "toDefend", "value": {"damage": cur.damage, "type": "surprise"}})
))
cur.status = Room.NOTHING
ene.status = Room.DEFENCE
else:
print("{} 受到{}點傷害,而且掉了一張手牌".format(ene.name,cur.damage))
r.append(( (wsene, wscur),
dumps({"msg": "surprised", "data": [ene.name, cur.damage]})
))
cur.status = Room.NOTHING
ene.life -= cur.damage
drop = random.choice(ene.hand)
ene.remove_card(drop)
cur.surprise = False
cur.damage = 0 # reset
cur.surprise = False
cur.damage = 0 # reset
r.extend(Room.start_turn(wsene, wscur))
return r
def trade(wscur,wsene):
cur, ene = wscur.player, wsene.player
r = []
if ene.hand:
r.append(( (wsene, wscur),
dumps({"msg": "trade", "data": [cur.name, ene.name]})
))
print("{} 想與 {} 進行交易".format(cur.name,ene.name))
cur.remove_card("7") # you can't trade the using card "trade"
game.display(cur) # 顯示手牌
while True:
choice = input("選擇一張手牌以交換 ")
if choice in cur.hand:
cur_item = choice
print("{} 選擇了 {}".format(cur.name,cards[choice]))
break
game.display(ene) # 顯示手牌
while True:
choice = input("選擇一張手牌以交換 ")
if choice in ene.hand:
ene_item = choice
print(ene.name,"choose",cards[choice])
break
# current player part
cur.hand.remove(cur_item)
cur.display.remove(cards[cur_item])
cur.hand.append(ene_item)
cur.display.append(cards[ene_item])
# enemy part
ene.hand.remove(ene_item)
ene.display.remove(cards[ene_item])
ene.hand.append(cur_item)
ene.display.append(cards[cur_item])
r.append(( (wscur,),
dumps({"action": "toTrade", "value": {"hand": cur.hand}}) # 更新已被移除的trade
))
cur.status = Room.TRADE
else:
r.append(( (wscur,wsene),
dumps({"msg": "tradeNoCard", "data": [cur.name]})
))
r.extend(Room.start_turn(wsene, wscur))
cur.add_card("7") # add back the card. game system will remove this card right away
return r
def aware(wscur,wsene):
cur, ene = wscur.player, wsene.player
r = []
if ene.attacking:
r.append(( (wsene,wscur), dumps({"msg": "awared", "data": [cur.name, ene.name, "攻擊"]})))
elif ene.robbing != "0":
r.append(((wscur, wsene), dumps({"msg": "awared", "data": [cur.name, ene.name, "搶奪"]})))
elif ene.surprise:
r.append(( (wsene,wscur), dumps({"msg": "awared", "data": [cur.name, ene.name, "奇襲"]})))
if cur.attacking:
print("{} 洞悉了 {} 的攻擊,並抽取了一張手牌".format(ene.name,cur.name))
game.draw(ene)
elif cur.robbing:
print("{} 洞悉了 {} 的強奪,並抽取了一張手牌".format(ene.name,cur.name))
game.draw(ene)
elif cur.surprise:
print("{} 洞悉了 {} 的奇襲,並抽取了一張手牌".format(ene.name,cur.name))
game.draw(ene)
else:
r.append(((wscur, wsene), dumps({"msg": "aware", "data": [cur.name]})))
for _ in range(3):
print("{} 增加三張手牌".format(cur.name))
game.draw(cur)
return r
def plan(wscur,wsene):
cur, ene = wscur.player, wsene.player
r = []
r.append(( (wsene, wscur),
dumps({"msg": "plan", "data": [cur.name]})
))
print("{} 有個妙策".format(cur.name))
options = random.sample(cur.deck,3)
o_name = [] # names of cards in options
for id in options:
o_name.append(cards[id])
print(o_name)
while True:
r.append(( (wscur, ),
dumps({"action": "toAdd", "value": {"cards": options}})
))
cur.planning = options
cur.status = Room.PLAN
"""while True:
choice = input("選擇一張卡加入手牌 ")
if choice in options:
cur.add_card(choice)
break
break"""
return r
def sweep(wscur,wsene):
cur, ene = wscur.player, wsene.player
cur.attacking = True
r = []
cur.damage = random.randint(0,5)
print("{}{} 進行掃射,威力是 {}".format(cur.name,ene.name,cur.damage))
r.append(( (wscur, wsene), dumps({"msg": "sweep", "data": [cur.name, ene.name, cur.damage]})))
if ene.defence():
game.display(ene) # 顯示手牌
while True:
choice = input("請問要防禦嗎? 不使用請輸入0 ")
if choice in ene.hand:
if choice in unattackable:
skills[choice](cur,ene)
ene.remove_card(choice)
break
elif choice == "0":
print("{} 受到{}點傷害".format(ene.name,cur.damage))
ene.life -= cur.damage
break
r.append(( (wsene, ),
dumps({"action": "toDefend", "value": {"damage": cur.damage, "type": "sweep"}})
))
cur.status = Room.NOTHING
ene.status = Room.DEFENCE
else:
print("{} 受到{}點傷害".format(ene.name,cur.damage))
r.append(( (wsene, wscur),
dumps({"msg": "damaged", "data": [ene.name, cur.damage]})
))
cur.status = Room.NOTHING
ene.life -= cur.damage
cur.attacking = False
cur.damage = 0 # reset
r.extend(Room.start_turn(wsene, wscur))
cur.attacking = False
cur.damage = 0 # reset
return r
def bless(wscur,wsene):
cur, ene = wscur.player, wsene.player
r = []
r.append(( (wsene,wscur), dumps({"msg": "bless", "data": [cur.name]})))
print("{} 獲得加護,身上的毒素一掃而空,並回復三點生命,還抽取了兩張手牌".format(cur.name))
cur.poison = 0 # 解毒
cur.life += 3
for _ in range(2):
game.draw(cur)
return r
def poison(wscur,wsene):
cur, ene = wscur.player, wsene.player
r = []
r.append(( (wsene,wscur), dumps({"msg": "poison", "data": [cur.name, ene.name]})))
if ene.poison != 0:
s = ""
else:
s = ""
print("{} 在食物下毒,{} {}中毒了".format(cur.name,ene.name, s))
ene.poison += 1
return r
def curse(wscur,wsene):
cur, ene = wscur.player, wsene.player
r = []
print("{} 詛咒了 {},使其損失四點生命,並掉了一張手牌".format(cur.name,ene.name))
ene.life -= 4
drop = random.choice(ene.hand)
ene.remove_card(drop)
msg = "curseNoCard"
if ene.hand:
drop = random.choice(ene.hand)
ene.remove_card(drop)
msg = "curse"
r.append(( (wsene,wscur), dumps({"msg": msg, "data": [cur.name, ene.name]})))
return r
def counter(wscur,wsene):
cur, ene = wscur.player, wsene.player
r = []
if cur.attacking:
print("{} 反制了 {} 的攻擊,反彈了{}點傷害".format(ene.name,cur.name,cur.damage))
cur.life -= cur.damage
elif cur.surprise:
print("{} 反制了 {} 的奇襲,反彈了{}點傷害,並使其掉了一張手牌".format(ene.name,cur.name,cur.damage))
cur -= cur.damage
drop = random.choice(cur.hand)
cur.remove_card(drop)
if ene.attacking:
r.append(( (wsene,wscur), dumps({"msg": "countered", "data": [cur.name, ene.name, ene.damage]})))
ene.life -= ene.damage
elif ene.surprise:
r.append(( (wsene,wscur), dumps({"msg": "counteredSur", "data": [cur.name, ene.name, ene.damage]})))
ene.life -= ene.damage
drop = random.choice(ene.hand)
ene.remove_card(drop)
else:
print("{} 反制了敵手,使 {} 生命值減半了!".format(cur.name,ene.name))
r.append(( (wsene,wscur), dumps({"msg": "counter", "data": [cur.name, ene.name]})))
ene.life = ene.life//2
return r
def chaos(wscur,wsene):
cur, ene = wscur.player, wsene.player
r = []
r.append(( (wsene,wscur), dumps({"msg": "reverse", "data": [cur.name, ene.name]})))
print("{} 進入狂亂模式,回復三點生命,並對 {} 造成三點傷害".format(cur.name,ene.name))
cur.life += 3
ene.life -= 3
return r
def reverse(wscur,wsene):
cur, ene = wscur.player, wsene.player
r = []
r.append(( (wsene,wscur), dumps({"msg": "reverse", "data": [cur.name]})))
print("{} 一口氣逆轉了情勢".format(cur.name))
cur.life,ene.life = ene.life,cur.life
return r
skills = dict()
skill_name = [attack,defend,heal,supply,rob,surprise,trade,aware,plan,sweep,bless,poison,curse,counter,chaos,reverse]
for i in range(len(skill_name)):
skills[str(i+1)] = skill_name[i]

53
game.py
View File

@ -8,13 +8,15 @@ class Player:
self.name = name
self.deck = deck[:] # to pass by value instead of by reference
self.hand = []
self.display = [] # names of cards in hand
self.life = 20
self.status = -1
self.life = 15
self.poison = 0
self.damage = 0 # 因為反制要拿來判斷掃射
self.playing = False
self.attacking = False
self.robbing = False
self.robbing = "0"
self.planning = [] # data temp for plan
self.trading = "0" # data temp for trade
self.surprise = False # 又是因為反制要判斷奇襲
self.turn = 0
@ -27,18 +29,17 @@ class Player:
def add_card(self,id):
self.hand.append(id)
self.display.append(card.cards[id])
self.deck.remove(id)
def remove_card(self,id):
self.hand.remove(id)
self.display.remove(card.cards[id])
self.deck.append(id)
def robbed(self,id): # be robbed
self.hand.remove(id)
self.display.remove(card.cards[id])
try:
self.hand.remove(id)
except:
print("rob except:", id, self.hand)
def defence(self): # to decide if player is able to defend or not
for c in self.hand:
if c in card.unattackable:
@ -65,7 +66,7 @@ def display(player):
def draw(player): # 抽卡
if len(player.deck) == 0:
player.life = -99999999 # 牌抽乾了就讓他死
return dumps({"msg": "noCard", "data": [player.name]})
return False
new = random.choice(player.deck)
player.add_card(new)
@ -73,37 +74,3 @@ def draw(player): # 抽卡
# turn control
# cur:current player
# ene:enemy
async def turn(wsp1,wsp2):
p1, p2 = wsp1.player, wsp2.player
wscur, wsene = (wsp1, wsp2) if p1.playing == True else (wsp2, wsp1)
cur, ene = wscur.player, wsene.player
cur.turn += 1
await wscur.send("{} 的第{}回合".format(cur.name,cur.turn))
if cur.poison_check():
await wscur.send("{} 受到了劇毒的侵蝕".format(cur.name))
await wscur.send("{} 損失{}點生命".format(cur.name,cur.poison))
if cur.life <= 0:
return
await sendTo(health(p1,p2), wsp1, wsp2)
await sendTo(draw(cur), wsp1, wsp2) # 抽卡
await sendTo(display(cur), wscur) # 顯示手牌
while True:
await sendTo("請問要使用手牌嗎? 若不使用請輸入0", wscur)
print("Wait receive")
choice = await wscur.recv()
print("Received")
if choice in cur.hand:
card.skills[choice](wscur, wsene)
cur.remove_card(choice)
break
elif choice == "0":
break
elif choice == "-1":
cur.surrender()
await sendTo("{}投降".format(cur.name), wsp1, wsp2)
break
del choice # prevent reading old data
p1.playing,p2.playing = p2.playing,p1.playing # switch!

123
pyws.py
View File

@ -3,11 +3,12 @@ import game
from room import Room, sendTo
import asyncio
import datetime
import random
import websockets
from json import dumps, loads
import ssl
connected = {-1: []}
character = dict()
name=["","圭月","","小兔","","正作","W","桑德","海爾","雪村"]
@ -18,6 +19,7 @@ for i in range(len(name)):
sad = None
fut = None
wait_fut = [0, 0]
async def wait(websocket, *cors, timeout=45, futs=None):
if futs != None:
fut_cor = futs
@ -25,33 +27,27 @@ async def wait(websocket, *cors, timeout=45, futs=None):
fut_cor = [cor() for cor in cors]
done, pending = await asyncio.wait(fut_cor,
return_when=asyncio.FIRST_EXCEPTION, timeout=timeout)
#print(done, pending)
#print("Futures:", done, pending)
if pending:
#print("coroutine doesn't finish its work")
pass
for task in pending:
task.cancel()
if len(done):
return list(done)[0].result()
else:
#print("SADDDDD")
return
def random_room():
global connected, rooms
try:
print(rooms)
except:
rooms = list(connected)
rooms.remove(-1)
print(rooms)
while len(rooms)>=1:
enter = random.choice(rooms)
print("rooms", enter, rooms)
rooms.remove(enter)
if list(done)[0].exception() == None:
return list(done)[0].result()
else:
return "exception"
def random_room(room_list):
while len(room_list)>=1:
enter = random.choice(room_list)
print("rooms", enter, room_list)
if len(connected[enter]) < 2:
return enter
while 1:
enter = random.randint(1, 99999)
if enter not in connected:
rooms.append(enter)
return enter
@ -66,7 +62,7 @@ async def enter_room(websocket):
message = await wait(websocket, websocket.recv)
if message == "n":
room_id = random_room()
room_id = random_room(room_list)
else:
room_id = int(message)
@ -91,15 +87,16 @@ async def enter_room(websocket):
for ws in connected[room_id]:
ws.status = Room.PLAYING
wsene = connected[room_id].players[0] if connected[room_id].players[1] is websocket else connected[room_id].players[1]
await ws.send(dumps({"room": room_id, "cur": websocket.player.name, "ene": wsene.player.name}))
wsene = connected[room_id].players[0] if connected[room_id].players[1] is ws else connected[room_id].players[1]
await ws.send(dumps({"room": room_id, "cur": ws.player.name, "ene": wsene.player.name}))
await ws.send(dumps({"msg": "firstAttack", "data": [players[0].player.name], "hand": ws.player.hand}))
fut.cancel()
for ws_list, message in Room.start_turn(*players):
await sendTo(message, *ws_list)
async def handler(websocket, path):
global connected,sad, fut
global connected,sad, fut, wait_fut, rooms
print("initialize")
# Register.
connected[-1].append(websocket)
websocket.status = Room.CONNECTED
@ -113,7 +110,8 @@ async def handler(websocket, path):
websocket.player = game.Player(name[int(choice)-1], card.default_deck)
websocket.status = Room.MATCHING
except:
except Exception as e:
print(e)
return # close the connection
@ -130,41 +128,92 @@ async def handler(websocket, path):
print("SAD", "FIRST" if websocket == sad else "SECOND")
fut = asyncio.ensure_future(websocket.recv())
try:
message = await wait(websocket, timeout=100000, futs=[fut])
message = await wait(websocket, timeout=100, futs=[fut])
print(message)
print(fut)
if message == "e":
connected[websocket.room].player_delete(websocket)
await websocket.send("You have left Room "+str(connected[websocket.room]))
del connected[websocket.room]
del websocket.room
connected[-1].append(websocket)
websocket.status = Room.MATCHING
elif message == "exception":
break
except asyncio.CancelledError:
pass
print("SADDDDDD", "FIRST" if websocket == sad else "SECOND")
elif websocket.status == Room.PLAYING:
print("wait for message", "FIRST" if websocket == sad else "SECOND")
message = await wait(websocket, websocket.recv, timeout=100000)
print("received message", "FIRST" if websocket == sad else "SECOND")
message_to_send = connected[websocket.room].process(websocket, message)
for ws_list, message in message_to_send:
await sendTo(message, *ws_list)
try:
enemy = 0 if websocket == connected[websocket.room].players[1] else 1
wait_fut[(enemy+1)%2] = asyncio.ensure_future(websocket.recv())
print("wait for", "FIRST" if websocket == sad else "SECOND")
message = await wait(websocket, timeout=30, futs=[wait_fut[(enemy+1)%2]])
print("received message", message)
print("FIRST" if websocket == sad else "SECOND", ":", message)
if message == "exception":
break
message_to_send = connected[websocket.room].process(websocket, message)
for ws_list, message in message_to_send:
await sendTo(message, *ws_list)
if message_to_send != []:
try:
if loads(message_to_send[-1][1])['msg'] == 'win': # 取最後一筆訊息的msg
connected[websocket.room].player_delete(websocket)
break
except KeyError:
pass
wait_fut[enemy].cancel() # 取消另一方的await
except asyncio.CancelledError:
print("FIRST" if websocket == sad else "SECOND", "was Canceled\n\n")
elif websocket.status == Room.DISCONNECT:
break
finally:
# Unregister.
try:
connected[websocket.room].player_delete(websocket)
if websocket not in connected[websocket.room]:
connected[websocket.room].players[0].status = Room.DISCONNECT
wait_fut[0].cancel()
wait_fut[1].cancel()
else:
if connected[websocket.room].player_delete(websocket):
await connected[websocket.room].players[0].send(dumps({"msg": "eneDisconn", "data": [connected[websocket.room].players[0].player.name]}))
connected[websocket.room].players[0].status = Room.DISCONNECT
wait_fut[0].cancel()
wait_fut[1].cancel()
# it will leave the loop and disconnect
if len(connected[websocket.room]) == 0: # clear the dictionary
print("delete")
del connected[websocket.room]
except:
connected[-1].remove(websocket)
print(connected)
"""cert = ssl.SSLContext()
cert = ssl.SSLContext()
cert.load_cert_chain("/etc/letsencrypt/live/stoneapp.tech/fullchain.pem","/etc/letsencrypt/live/stoneapp.tech/privkey.pem")
start_server = websockets.serve(handler, '10.128.0.2', 8787,ssl=cert)"""
start_server = websockets.serve(handler, '10.128.0.2', 8787,ssl=cert)
start_server = websockets.serve(handler, '127.0.0.1', 9000)
#start_server = websockets.serve(handler, '127.0.0.1', 9000)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()

183
room.py
View File

@ -1,12 +1,12 @@
import game, card
import random
from json import dumps, loads
class Room:
CONNECTED = 0
MATCHING = 1
PLAYING = 2
WAITING = -1
DISCONNECT = -2
# Player Status Definition
NOTHING = -1
@ -15,7 +15,8 @@ class Room:
DEFENCE = 2
ROBBING = 3
TRADE = 4
PLAN = 5
TRADE_ENE = 5
PLAN = 6
def __init__(self, room):
self.room = room
self.players = []
@ -38,6 +39,10 @@ class Room:
def player_delete(self, player):
try:
self.players.remove(player)
if len(self) == 1:
return True
else:
return False
except:
pass
@ -84,36 +89,62 @@ class Room:
message_to_send = []
cur.playing, ene.playing = ene.playing, cur.playing
cur.turn += 1
draw_res = game.draw(cur)
if not draw_res:
message_to_send.append(( (wscur, wsene), dumps({"msg": "noCard", "data": [cur.name]})))
else:
message_to_send.append(( (wscur,), draw_res))
message_to_send.append(( (wscur,), game.draw(cur)))
message_to_send.append(( (wscur,),
dumps({"player": {
"turn": cur.turn, "hand": cur.hand, "deck_left": len(cur.deck),
"life": cur.life
if cur.poison_check():
message_to_send.append(( (wscur,wsene), dumps({"msg": "poisonDamaged", "data": [cur.name,cur.poison]})))
message_to_send.append(( (wscur,),
dumps({"player": {
"turn": cur.turn, "hand": cur.hand, "deck_left": len(cur.deck),
"life": cur.life, "poison": cur.poison,
},
"enemy": {
"life": ene.life, "deck_left": len(ene.deck),
"hand": len(ene.hand), "poison": ene.poison,
},
"now": "player",
}
}
)
))
)
))
message_to_send.append(( (wsene,),
dumps({"enemy": {
"turn": cur.turn, "deck_left": len(cur.deck),
"life": cur.life # cur為當前回合之玩家故此處仍為cur
message_to_send.append(( (wsene,),
dumps({"player": {
"turn": ene.turn, "hand": ene.hand, "deck_left": len(ene.deck),
"life": ene.life, "poison": ene.poison,
},
"enemy": {
"turn": cur.turn, "deck_left": len(cur.deck),
"life": cur.life, "hand": len(cur.hand), "poison": cur.poison,
# cur為當前回合之玩家故此處仍為cur
},
"now": "enemy"
}
}
)
))
)
))
message_to_send.append(( (wsene,), dumps({"msg": "drawEne", "data": [cur.name]})))
message_to_send.append(( (wsene,), dumps({"msg": "drawEne", "data": [cur.name]})))
cur.status = Room.IN_TURN
cur.status = Room.IN_TURN
if cur.poison_check():
message_to_send.append(( (wscur,wsene), "{} 受到了劇毒的侵蝕, 損失{}點生命".format(cur.name,cur.poison)))
if cur.life <= 0:
pass
message_to_send.append(( (wscur,), dumps({"msg": "win", "data": ["enemy"]})))
message_to_send.append(( (wsene,), dumps({"msg": "win", "data": ["player"]})))
elif ene.life <= 0:
message_to_send.append(( (wscur,), dumps({"msg": "win", "data": ["player"]})))
message_to_send.append(( (wsene,), dumps({"msg": "win", "data": ["enemy"]})))
#await sendTo(health(p1,p2), wsp1, wsp2)
#await sendTo(draw(cur), wsp1, wsp2) # 抽卡
#message_to_send.append(( (wscur,), game.display(cur))) # 顯示手牌
@ -128,50 +159,134 @@ class Room:
ene = wsene.player
message_to_send = []
choice = message
if cur.status == self.IN_TURN:
if choice in cur.hand:
message_to_send.append(((wsene, wscur), dumps({"msg": "use", "data": [cur.name, choice]})))
cur.remove_card(choice)
message_to_send.extend(card.skills[choice](wscur, wsene))
if choice in start_next_turn_cards:
cur.status = self.NOTHING
message_to_send.extend(Room.start_turn(wsene, wscur))
cur.remove_card(choice)
elif choice == "0":
else: # 直接結束
cur.status = self.NOTHING
message_to_send.extend(Room.start_turn(wsene, wscur))
"""elif choice == "-1":
cur.surrender()
{}投降".format(cur.name)"""
elif cur.status == self.ROBBING:
pass
swag = choice
ene.status = self.NOTHING
if swag in ene.hand:
cur.robbing = swag
if ene.keep():
cur.status = Room.NOTHING
ene.status = Room.ROBBED
message_to_send.append(((wsene, ), dumps({"action": "toBeRobbed"})))
else:
ene.robbed(swag)
cur.add_card(swag)
message_to_send.append(( (wscur,wsene), dumps({"msg": "robbed", "data": [cur.name, cur.robbing]})))
cur.robbing = "0"
cur.status = Room.NOTHING
message_to_send.extend(Room.start_turn(wsene, wscur))
else: # 直接結束
message_to_send.append(((wsene, wscur), dumps({"msg": "cantRob", "data": [cur.name]})))
message_to_send.extend(Room.start_turn(wsene, wscur))
elif cur.status == self.ROBBED:
pass
if choice in cur.hand and choice in card.unrobable:
message_to_send.extend(card.skills[choice](wscur,wsene))
cur.remove_card(choice)
else:
message_to_send.append(( (wscur,wsene), dumps({"msg": "robbed", "data": [ene.name, ene.robbing]})))
cur.robbed(ene.robbing)
ene.add_card(ene.robbing)
ene.robbing = "0"
message_to_send.extend(Room.start_turn(wscur, wsene))
elif cur.status == self.DEFENCE: # cur是被攻擊方
if choice in cur.hand:
if choice in card.unattackable:
message_to_send.extend(card.skills[choice](wscur,wsene))
cur.remove_card(choice)
elif choice == "0":
message_to_send.append(( (wsene, wscur), "{} 受到{}點傷害".format(cur.name,ene.damage)))
ene.life -= cur.damage
else:
if ene.surprise:
msg = "surNoCard"
if ene.hand:
drop = random.choice(ene.hand)
ene.remove_card(drop)
msg = "surprised"
message_to_send.append(( (wsene, wscur), dumps({"msg": msg, "data": [cur.name, ene.damage]})))
else:
message_to_send.append(( (wsene, wscur), dumps({"msg": "damaged", "data": [cur.name, ene.damage]})))
cur.life -= ene.damage
else:
message_to_send.append(( (wscur,wsene), "{} 受到{}點傷害".format(cur.name,ene.damage)))
cur.life -= cur.damage
if ene.surprise:
drop = random.choice(ene.hand)
ene.remove_card(drop)
message_to_send.append(( (wsene, wscur), dumps({"msg": "surprised", "data": [cur.name, ene.damage]})))
else:
message_to_send.append(( (wsene, wscur), dumps({"msg": "damaged", "data": [cur.name, ene.damage]})))
cur.life -= ene.damage
ene.attacking = False
ene.surprise = False # 兩個都取消
ene.damage = 0 # reset
message_to_send.extend(Room.start_turn(wscur, wsene))
elif cur.status == self.TRADE:
pass
if choice in cur.hand:
message_to_send.append(( (wsene, wscur), dumps({"msg": "tradeChoose", "data": [cur.name, choice]})))
message_to_send.append(( (wsene,), dumps({"action": "toTrade"})))
cur.trading = choice
cur.status = self.NOTHING
ene.status = self.TRADE_ENE
else: # 直接結束
message_to_send.extend(Room.start_turn(wsene, wscur))
elif cur.status == self.TRADE_ENE:
if cur.hand:
if choice not in cur.hand:
choice = random.sample(cur.hand, 1)[0] # decide a card randomly
ene.hand.remove(ene.trading)
ene.hand.append(choice)
cur.hand.remove(choice)
cur.hand.append(ene.trading)
else:
message_to_send.append(( (wsene,wscur), dumps( {"msg": "tradeNoCard", "data": [cur.name]})))
ene.trading = "0"
message_to_send.extend(Room.start_turn(wscur, wsene))
elif cur.status == self.PLAN:
pass
if choice in cur.planning:
cur.add_card(choice)
cur.stauts = Room.NOTHING
cur.planning = []
message_to_send.extend(Room.start_turn(wsene, wscur))
print("status of ",cur.name, ":", cur.status)
print("status of ",ene.name, ":", ene.status)
return message_to_send
async def sendTo(message, *ws_list):
for ws in ws_list:

View File

@ -1,7 +1,7 @@
choose character: "5"
enter_room: room number / "n" // "n" to create a random room and enter it
out: room number / {"room": 18693, "cur": "圭月", "ene": "小兔"}
out: room number / {"room": 7122, "cur": "圭月", "ene": "小兔"}
// shows room number, or send a object shows your player and enemy's
:
@ -12,13 +12,14 @@ enter_room: room number / "n" // "n" to create a random room and enter it
{
"player": {
"turn": 3, "hand": ['1','2','3','1','1','1'], "deck_left": 35,
"life": 20
"life": 20, "poison": 0,
},
"enemy": {"turn": 3, "life": 20, "deck_left": 35
"enemy": {"turn": 3, "life": 20, "deck_left": 35, "hand": 30, "poison": 1,
}
}
{
"attack": "{} 攻擊 {}",
"damaged": "{} 受到{}點傷害",
@ -28,8 +29,8 @@ enter_room: room number / "n" // "n" to create a random room and enter it
"heal": "{} 回復兩點生命",
"supply": "{} 增加兩張手牌",
"rob": "{} 正在對 {} 行搶",
"cantRob": "可惜,{} 有夠窮,沒東西能搶",
"robbed": "{} 搶到了 {}"
"cantRob": "{}沒有搶到任何東西",
"robbed": "{} 搶到了 {}",
"surprise": "{} 發動奇襲",
"surprised": "{} 受到{}點傷害,而且掉了一張手牌",
"trade": "{} 想與 {} 進行交易",
@ -66,7 +67,9 @@ enter_room: room number / "n" // "n" to create a random room and enter it
"firstAttack": "{}先攻",
"win": "{}獲勝",
"draw": "{}抽到了{}",
"drawEne": "{}抽了一張卡片"
"drawEne": "{}抽了一張卡片",
"use": "{}使用了{}",
"eneDisconn": "因敵方斷線,所以{}獲勝",
}
@ -76,13 +79,13 @@ enter_room: room number / "n" // "n" to create a random room and enter it
in: "1"
out:
cur: {"msg": "attack", "data": [cur.name, ene.name]}
ene: {"msg": "attack", "data": [cur.name, ene.name],
"action": "toDefend", "value": {"damage": cur.damage}} / ()
ene: cur, {"action": "toDefend", "value": {"damage": cur.damage, "type": "attack"}} /
cur()
in: "2" / "8" / "14" / "0"
out:
cur: {"msg": "defended", "data": [ene.name]} /
{"msg": "countered", "data": [ene.name]} /
{"msg": "awared", "data": [ene.name, "攻擊"]} /
{"msg": "awared", "data": [cur.name, ene.name, "攻擊"]} /
{"msg": "damaged", "data": [ene.name, cur.damage]}
ene:
2. defend //使
@ -104,37 +107,39 @@ enter_room: room number / "n" // "n" to create a random room and enter it
in: "5"
out:
cur: {"msg": "rob", "data": [cur.name, ene.name],
"action": "toRob", "value": {"emeny_card:", ene.hand}} /
{"msg": "cantRob", "data": [ene.name]}
"action": "toRob", "value": {"enemy_card": ene.hand}} /
{{"msg": "cantRob", "data": [cur.name]}]}
in: card number
out:
ene: {"action": "toBeRobbed"} / ()
ene: {"action": "toBeRobbed"} / ()
in: "8" / "0"
out:
cur: {"msg": "defended", "data": [ene.name]} /
cur: {"msg": "awared", "data": [cur.name, ene.name, "搶奪"]} /
{"msg": "robbed", "data": [ene.name, card]}
ene:
ene: / {"msg": "cantRob", "data": [ene.name]}
ene: / {{"msg": "cantRob", "data": [cur.name]}]}
6. surprise
in: "6"
out:
cur:
ene: {"action": "toDefend", "value": {"damage": cur.damage}} / ()
cur: {"msg": "surprise", "data": [cur.name]}
ene: cur, {"action": "toDefend", "value": {"damage": cur.damage, "type": "suprise"}} /
cur()
in: "2" / "8" / "14" / "0"
out:
cur: {"msg": "defended", "data": [ene.name]} /
{"msg": "counteredSur", "data": [ene.name]} /
{"msg": "awared", "data": [ene.name, "奇襲"]} /
{"msg": "awared", "data": [cur.name, ene.name, "奇襲"]} /
{"msg": "surprised", "data": [ene.name, cur.damage]}
ene:
7. trade
in: "7"
out:
cur: {"msg": "trade", "data": [cur.name, ene.name], "action": "toTrade"}
cur: {"msg": "trade", "data": [cur.name, ene.name]},
{"action": "toTrade", "value": ["hand": cur.hand]}
in: card number
out:
cur: {"msg": "tradeChoose", "data": [cur.name, card number]}
ene: {"action": "toTrade"}
ene: cur, {"action": "toTrade"}
ene: {"msg": "trade", "data": [cur.name, ene.name]}
8. aware //使
in: "8"
@ -144,8 +149,8 @@ enter_room: room number / "n" // "n" to create a random room and enter it
9. plan
in: "9"
out:
cur: {"msg": "plan", "data": [cur.name],
"action": "toAdd", "value": {"cards": list}}
cur: {"msg": "plan", "data": [cur.name]},
{"action": "toAdd", "value": {"cards": list}}
in: card number
ene: {"msg": "plan", "data": [cur.name]}
10. bless
@ -156,13 +161,14 @@ enter_room: room number / "n" // "n" to create a random room and enter it
11. sweep
in: "11"
out:
cur:
ene: {"action": "toDefend", "value": {"damage": cur.damage}} / ()
cur: {"msg": "sweep", "data": [cur.name, ene.name, cur.damage]}
ene: cur, {"action": "toDefend", "value": {"damage": cur.damage, "type": "sweep"}} /
()
in: "2" / "8" / "14" / "0"
out:
cur: {"msg": "defended", "data": [ene.name]} /
{"msg": "countered", "data": [ene.name]} /
{"msg": "awared", "data": [ene.name, "掃射"]} /
{"msg": "awared", "data": [cur.name, ene.name, "掃射"]} /
{"msg": "damaged", "data": [ene.name, cur.damage]}
ene:
12. poison