choosing character and entering room, room.py is testing
This commit is contained in:
238
card.py
Normal file
238
card.py
Normal file
@@ -0,0 +1,238 @@
|
||||
import random
|
||||
import game
|
||||
|
||||
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']
|
||||
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', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '8', '8', '8', '8', '8', '9', '9', '9', '9', '9', '10', '10', '10', '10', '10', '11', '11', '11', '11', '11', '12', '12', '13', '13', '14', '14', '15', '15', '16', '16']
|
||||
random.shuffle(default_deck) # wash
|
||||
|
||||
# card functions
|
||||
# cur:current player
|
||||
# ene:enemy
|
||||
def attack(cur,ene):
|
||||
cur.attacking = True
|
||||
cur.damage = 2 # 給反制判斷的
|
||||
print("{} 攻擊 {}".format(cur.name,ene.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
|
||||
break
|
||||
else:
|
||||
print("{} 受到{}點傷害".format(ene.name,cur.damage))
|
||||
ene.life -= cur.damage
|
||||
cur.attacking = False
|
||||
cur.damage = 0 # reset
|
||||
|
||||
def defend(cur,ene):
|
||||
if cur.attacking or cur.surprise:
|
||||
print("{} 防禦成功".format(ene.name))
|
||||
else:
|
||||
print("{} 沒什麼可以防禦的,回復一點生命".format(cur.name))
|
||||
cur.life += 1
|
||||
|
||||
def heal(cur,ene):
|
||||
print("{} 回復兩點生命".format(cur.name))
|
||||
cur.life += 2
|
||||
|
||||
def supply(cur,ene):
|
||||
print("{} 增加兩張手牌".format(cur.name))
|
||||
for _ in range(2):
|
||||
game.draw(cur)
|
||||
|
||||
def rob(cur,ene):
|
||||
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
|
||||
|
||||
def surprise(cur,ene):
|
||||
cur.surprise = True
|
||||
cur.damage = 1 # 給反制判斷
|
||||
print("{} 發動奇襲".format(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
|
||||
else:
|
||||
print("{} 受到{}點傷害,而且掉了一張手牌".format(ene.name,cur.damage))
|
||||
ene.life -= cur.damage
|
||||
drop = random.choice(ene.hand)
|
||||
ene.remove_card(drop)
|
||||
cur.surprise = False
|
||||
cur.damage = 0 # reset
|
||||
|
||||
def trade(cur,ene):
|
||||
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])
|
||||
|
||||
cur.add_card("7") # add back the card. game system will remove this card right away
|
||||
|
||||
def aware(cur,ene):
|
||||
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:
|
||||
for _ in range(3):
|
||||
print("{} 增加三張手牌".format(cur.name))
|
||||
game.draw(cur)
|
||||
|
||||
def plan(cur,ene):
|
||||
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:
|
||||
choice = input("選擇一張卡加入手牌 ")
|
||||
if choice in options:
|
||||
cur.add_card(choice)
|
||||
break
|
||||
|
||||
def sweep(cur,ene):
|
||||
cur.attacking = True
|
||||
cur.damage = random.randint(0,5)
|
||||
print("{} 對 {} 進行掃射,威力是 {}".format(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
|
||||
else:
|
||||
print("{} 受到{}點傷害".format(ene.name,cur.damage))
|
||||
ene.life -= cur.damage
|
||||
cur.attacking = False
|
||||
cur.damage = 0 # reset
|
||||
|
||||
def bless(cur,ene):
|
||||
print("{} 獲得加護,身上的毒素一掃而空,並回復三點生命,還抽取了兩張手牌".format(cur.name))
|
||||
cur.poison = 0 # 解毒
|
||||
cur.life += 3
|
||||
for _ in range(2):
|
||||
game.draw(cur)
|
||||
|
||||
def poison(cur,ene):
|
||||
if ene.poison != 0:
|
||||
s = "又"
|
||||
else:
|
||||
s = ""
|
||||
print("{} 在食物下毒,{} {}中毒了".format(cur.name,ene.name, s))
|
||||
ene.poison += 1
|
||||
|
||||
def curse(cur,ene):
|
||||
print("{} 詛咒了 {},使其損失四點生命,並掉了一張手牌".format(cur.name,ene.name))
|
||||
ene.life -= 4
|
||||
drop = random.choice(ene.hand)
|
||||
ene.remove_card(drop)
|
||||
|
||||
def counter(cur,ene):
|
||||
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)
|
||||
else:
|
||||
print("{} 反制了敵手,使 {} 生命值減半了!".format(cur.name,ene.name))
|
||||
ene.life = ene.life//2
|
||||
|
||||
def chaos(cur,ene):
|
||||
print("{} 進入狂亂模式,回復三點生命,並對 {} 造成三點傷害".format(cur.name,ene.name))
|
||||
cur.life += 3
|
||||
ene.life -= 3
|
||||
|
||||
def reverse(cur,ene):
|
||||
print("{} 一口氣逆轉了情勢".format(cur.name))
|
||||
cur.life,ene.life = ene.life,cur.life
|
||||
|
||||
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]
|
||||
107
game.py
Normal file
107
game.py
Normal file
@@ -0,0 +1,107 @@
|
||||
import random
|
||||
import card
|
||||
|
||||
class Player:
|
||||
def __init__(self,name,deck):
|
||||
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.poison = 0
|
||||
self.damage = 0 # 因為反制要拿來判斷掃射
|
||||
self.playing = False
|
||||
self.attacking = False
|
||||
self.robbing = False
|
||||
self.surprise = False # 又是因為反制要判斷奇襲
|
||||
self.turn = 0
|
||||
|
||||
def poison_check(self):
|
||||
if self.poison != 0:
|
||||
self.life -= self.poison
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
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])
|
||||
|
||||
def defence(self): # to decide if player is able to defend or not
|
||||
for c in self.hand:
|
||||
if c in card.unattackable:
|
||||
return True
|
||||
return False
|
||||
|
||||
def keep(self): # to decide if player is able to be robbed or not
|
||||
for c in self.hand:
|
||||
if c in card.unrobable:
|
||||
return True
|
||||
return False
|
||||
def surrender(self):
|
||||
self.life = 0
|
||||
|
||||
# game functions
|
||||
def health(p1,p2):
|
||||
print("{} 的生命: {}".format(p1.name,p1.life))
|
||||
print("{} 的生命: {}".format(p2.name,p2.life))
|
||||
|
||||
def display(player):
|
||||
print("這是 {} 的手牌".format(player.name))
|
||||
print(player.display)
|
||||
|
||||
def draw(player): # 抽卡
|
||||
if len(player.deck) == 0:
|
||||
player.life = -99999999 # 牌抽乾了就讓他死
|
||||
print("你抽到了死神")
|
||||
return None
|
||||
new = random.choice(player.deck)
|
||||
print("{} 抽到了 {}".format(player.name,card.cards[new]))
|
||||
player.add_card(new)
|
||||
print("牌組剩餘: {} 張".format(len(player.deck)))
|
||||
|
||||
# turn control
|
||||
# cur:current player
|
||||
# ene:enemy
|
||||
def turn(p1,p2):
|
||||
if p1.playing == True:
|
||||
cur = p1
|
||||
ene = p2
|
||||
elif p2.playing == True:
|
||||
cur = p2
|
||||
ene = p1
|
||||
cur.turn += 1
|
||||
print("") # change line
|
||||
print("{} 的第{}回合".format(cur.name,cur.turn))
|
||||
if cur.poison_check():
|
||||
print("{} 受到了劇毒的侵蝕".format(cur.name))
|
||||
print("{} 損失{}點生命".format(cur.name,cur.poison))
|
||||
if cur.life <= 0:
|
||||
return
|
||||
health(p1,p2)
|
||||
draw(cur) # 抽卡
|
||||
display(cur) # 顯示手牌
|
||||
while True:
|
||||
choice = input("請問要使用手牌嗎? 若不使用請輸入0 ")
|
||||
if choice in cur.hand:
|
||||
card.skills[choice](cur,ene)
|
||||
cur.remove_card(choice)
|
||||
break
|
||||
elif choice == "0":
|
||||
break
|
||||
elif choice == "-1":
|
||||
cur.surrender()
|
||||
print("{}投降".format(cur.name))
|
||||
break
|
||||
del choice # prevent reading old data
|
||||
p1.playing,p2.playing = p2.playing,p1.playing # switch!
|
||||
86
pyws.py
Normal file
86
pyws.py
Normal file
@@ -0,0 +1,86 @@
|
||||
import card
|
||||
import game
|
||||
from room import Room, sendTo
|
||||
|
||||
import asyncio
|
||||
import datetime
|
||||
import random
|
||||
import websockets
|
||||
|
||||
|
||||
connected = {-1: []}
|
||||
character = dict()
|
||||
name=["安","圭月","梅","小兔","銀","正作","W","桑德","海爾","雪村"]
|
||||
|
||||
for i in range(len(name)):
|
||||
character[str(i+1)] = name[i]
|
||||
|
||||
async def handler(websocket, path):
|
||||
global connected
|
||||
# Register.
|
||||
connected[-1].append(websocket)
|
||||
websocket.status = Room.CONNECTED
|
||||
await websocket.send("CHOOSE CHARACTER")
|
||||
try:
|
||||
# Implement logic here.
|
||||
while 1:
|
||||
message = await websocket.recv()
|
||||
if websocket.status == Room.CONNECTED: # choose character
|
||||
choice = message
|
||||
while choice not in map(lambda x : str(x+1),list(range(len(name)))):
|
||||
await websocket.send("CHOOSE")
|
||||
await websocket.send("CHOOSE: "+ str(choice) + "\n" + str(list(range(len(name)))))
|
||||
choice = await websocket.recv()
|
||||
p_name = character[choice]
|
||||
await websocket.send("PLAYER "+p_name)
|
||||
websocket.player = game.Player(p_name,card.default_deck)
|
||||
|
||||
websocket.status = Room.MATCHING
|
||||
|
||||
elif websocket.status == Room.MATCHING:
|
||||
try:
|
||||
room_id = int(message)
|
||||
connected[room_id] = connected.get(room_id, Room(room_id))
|
||||
|
||||
count = connected[room_id].count()
|
||||
|
||||
if count <= 1: # Enter the room
|
||||
connected[room_id].player_add(websocket)
|
||||
connected[-1].remove(websocket)
|
||||
await websocket.send("You have entered room "+ str(connected[room_id]))
|
||||
websocket.room = room_id
|
||||
|
||||
if count+1 == 1: # 該玩家已加入房間
|
||||
await websocket.send("Waiting for another player...")
|
||||
else:
|
||||
for ws in connected[room_id]:
|
||||
ws.status = Room.PLAYING
|
||||
await ws.send("The game will start soon.....")
|
||||
# await connected[room_id].start()
|
||||
# Testing
|
||||
|
||||
else: # Can't enter the room
|
||||
await websocket.send("SAD, This room is full. Please enter another room.")
|
||||
except Exception as e:
|
||||
print(e)
|
||||
print("STATUS = MATCHING")
|
||||
elif websocket.status == Room.PLAYING:
|
||||
print("STATUS = PLAYING, message got")
|
||||
for ws in connected[websocket.room]:
|
||||
await ws.send("STARTING... But unfortunately, we haven't completed this part of code.")
|
||||
print("STATUS = PLAYING, message sent")
|
||||
|
||||
finally:
|
||||
# Unregister.
|
||||
connected[websocket.room].player_delete(websocket)
|
||||
print(connected)
|
||||
|
||||
|
||||
|
||||
"""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, '127.0.0.1', 9000)
|
||||
asyncio.get_event_loop().run_until_complete(start_server)
|
||||
asyncio.get_event_loop().run_forever()
|
||||
55
room.py
Normal file
55
room.py
Normal file
@@ -0,0 +1,55 @@
|
||||
import game
|
||||
import random
|
||||
|
||||
class Room:
|
||||
CONNECTED = 0
|
||||
MATCHING = 1
|
||||
PLAYING = 2
|
||||
WAITING = -1
|
||||
def __init__(self, room, players=[]):
|
||||
self.room = room
|
||||
self.players = players
|
||||
|
||||
def __repr__(self):
|
||||
return "ROOM {}, {} player(s)".format(str(self.room), len(self.players))
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.players)
|
||||
|
||||
def player_add(self, player):
|
||||
if self.count() >= 2:
|
||||
return
|
||||
self.players.append(player)
|
||||
|
||||
def player_delete(self, player):
|
||||
try:
|
||||
self.players.remove(player)
|
||||
except:
|
||||
pass
|
||||
|
||||
def count(self):
|
||||
return len(self.players)
|
||||
|
||||
async def start(self):
|
||||
p1, p2 = self.players[0].player, self.players[1].player
|
||||
first = random.choice([p1, p2])
|
||||
print(first, p1, p2)
|
||||
first.playing = True # so the first one will be random
|
||||
await sendTo(first.name + "先攻", *self.players)
|
||||
print(first.name,"先攻")
|
||||
print() # change line
|
||||
for _ in range(3): # 初始手牌*3
|
||||
game.draw(p1)
|
||||
game.draw(p2)
|
||||
|
||||
while p1.life > 0 and p2.life > 0:
|
||||
await game.turn(self.players[0], self.players[1])
|
||||
|
||||
if p1.life <= 0:
|
||||
print("{} 獲勝".format(p2.name))
|
||||
elif p2.life <= 0:
|
||||
print("{} 獲勝".format(p1.name))
|
||||
|
||||
async def sendTo(message, *ws_list):
|
||||
for ws in ws_list:
|
||||
await ws.send(message)
|
||||
Reference in New Issue
Block a user