最终整理版
This commit is contained in:
@@ -0,0 +1,232 @@
|
||||
extends NpcScript
|
||||
|
||||
# Behaviour
|
||||
const ThresholdHandValue : int = 17
|
||||
|
||||
# Card utilities
|
||||
static var RANKS : PackedStringArray = ["王牌", "2", "3", "4", "5", "6", "7", "8", "9", "10", "侍从", "王后", "国王"]
|
||||
static var SUITS : PackedStringArray = [
|
||||
"黑桃",
|
||||
"红心",
|
||||
"方片",
|
||||
"梅花"
|
||||
]
|
||||
|
||||
# Game state
|
||||
var deck : Array = []
|
||||
var playerHand : Array = []
|
||||
var dealerHand : Array = []
|
||||
|
||||
# Helper
|
||||
static func _CardName(card : int) -> String:
|
||||
return "%s%s" % [SUITS[floori(card / 13.0)], RANKS[card % 13]]
|
||||
|
||||
static func _CardValue(card : int) -> int:
|
||||
var rank : int = card % 13
|
||||
if rank == 0: return 11
|
||||
if rank >= 10: return 10
|
||||
return rank + 1
|
||||
|
||||
static func _HandValue(hand : Array) -> int:
|
||||
var value : int = 0
|
||||
var aces : int = 0
|
||||
for card : int in hand:
|
||||
value += _CardValue(card)
|
||||
if card % 13 == 0:
|
||||
aces += 1
|
||||
while value > 21 and aces > 0:
|
||||
value -= 10
|
||||
aces -= 1
|
||||
return value
|
||||
|
||||
static func _HandStr(hand : Array) -> String:
|
||||
var parts : PackedStringArray = []
|
||||
for card : int in hand:
|
||||
parts.append(_CardName(card))
|
||||
return ", ".join(parts) + " (%d)" % _HandValue(hand)
|
||||
|
||||
static func _NewDeck() -> Array:
|
||||
var d : Array = []
|
||||
d.resize(52)
|
||||
for i : int in range(52):
|
||||
d[i] = i
|
||||
d.shuffle()
|
||||
return d
|
||||
|
||||
# General flow
|
||||
func OnStart():
|
||||
Mes("欢迎,欢迎!你是来找人,还是来找一局好牌?")
|
||||
Mes("听过 21 点 吗?别被名字吓到,规矩简单,胆量和分寸才是关键。")
|
||||
Mes("坐下吧。图利姆沙 的风会吹乱很多东西,但吹不乱一副洗好的牌。")
|
||||
DisplayChoices()
|
||||
|
||||
func DisplayChoices():
|
||||
Choice("挑战 海兰德", StartDealer)
|
||||
Choice("帮我找个对手", StartPvP)
|
||||
Choice("讲讲规则", ShowRules)
|
||||
Choice("今天先不玩", Decline)
|
||||
|
||||
func ShowRules():
|
||||
Mes("规则很简单:尽量接近 21 点,但不能超过。")
|
||||
Mes("数字牌按牌面算,花牌都算 10。王牌可以算 1,也可以算 11,看哪种对你更有利。")
|
||||
Mes("比我点数高且不爆牌,你就赢。超过 21,就是爆牌。")
|
||||
Mes("这游戏最难的不是加法,是知道什么时候该停手。许多商人一辈子都没学会。")
|
||||
DisplayChoices()
|
||||
|
||||
func Decline():
|
||||
Chat("想玩牌的时候来找我。好牌不会等人太久。")
|
||||
|
||||
func OnQuit():
|
||||
if npc and npc.ownScript:
|
||||
npc.ownScript.call("LeavePvP", own)
|
||||
super.OnQuit()
|
||||
|
||||
# Player vs Dealer Mode
|
||||
func StartDealer():
|
||||
deck = _NewDeck()
|
||||
playerHand = [deck.pop_back(), deck.pop_back()]
|
||||
dealerHand = [deck.pop_back(), deck.pop_back()]
|
||||
_DealerTurn()
|
||||
|
||||
func _DealerTurn():
|
||||
if _HandValue(playerHand) == 21:
|
||||
_DealerReveal()
|
||||
else:
|
||||
Mes("你的手牌:%s" % _HandStr(playerHand))
|
||||
Mes("我明面上的牌:%s。" % _CardName(dealerHand[0]))
|
||||
Choice("要牌", _DealerHit)
|
||||
Choice("停牌", _DealerReveal)
|
||||
|
||||
func _DealerHit():
|
||||
playerHand.append(deck.pop_back())
|
||||
var value : int = _HandValue(playerHand)
|
||||
if value > 21:
|
||||
Mes("你的手牌:%s" % _HandStr(playerHand))
|
||||
Mes("哎呀,爆牌了!贪心常常只差一张牌,我见过太多次。")
|
||||
Choice("再来一局", StartDealer)
|
||||
Choice("离开", Decline)
|
||||
elif value == 21:
|
||||
_DealerReveal()
|
||||
else:
|
||||
_DealerTurn()
|
||||
|
||||
func _DealerReveal():
|
||||
while _HandValue(dealerHand) < ThresholdHandValue:
|
||||
dealerHand.append(deck.pop_back())
|
||||
var pv : int = _HandValue(playerHand)
|
||||
var dv : int = _HandValue(dealerHand)
|
||||
Mes("你的手牌:%s" % _HandStr(playerHand))
|
||||
Mes("我的手牌:%s" % _HandStr(dealerHand))
|
||||
if dv > 21:
|
||||
Mes("哈!老手也有伸手太长的时候。你赢得漂亮。")
|
||||
elif pv > dv:
|
||||
Mes("嗯,不错。你知道什么时候该停。")
|
||||
elif dv > pv:
|
||||
Mes("经验又赢了一次。别难过,多数人第一次都输给我。")
|
||||
else:
|
||||
Mes("%d 点平局!胆子不错,我承认这一点。" % pv)
|
||||
Choice("再来一局", StartDealer)
|
||||
Choice("离开", Decline)
|
||||
|
||||
# Player vs Player Mode
|
||||
func StartPvP():
|
||||
var result : int = npc.ownScript.call("JoinPvP", own)
|
||||
if result == 0:
|
||||
Mes("好,让我们看看还有谁有胆量坐上这张桌子。稍等。")
|
||||
Choice("查看", _PvPCheck)
|
||||
Choice("取消", _PvPCancel)
|
||||
else:
|
||||
_PvPBegin()
|
||||
|
||||
func _PvPCheck():
|
||||
var game : Dictionary = npc.ownScript.call("GetGame", own)
|
||||
if game.is_empty():
|
||||
Mes("耐心点。好牌手要先学会等待。")
|
||||
Choice("查看", _PvPCheck)
|
||||
Choice("取消", _PvPCancel)
|
||||
elif game.has("result"):
|
||||
_PvPShowResult(game)
|
||||
else:
|
||||
_PvPBegin()
|
||||
|
||||
func _PvPCancel():
|
||||
npc.ownScript.call("LeavePvP", own)
|
||||
Chat("没有牌局?可惜。也许风向一变,你又想玩了。")
|
||||
func _PvPBegin():
|
||||
playerHand = npc.ownScript.call("GetHand", own)
|
||||
Mes("哈!对手来了。让我看看你们谁更懂停手。")
|
||||
_PvPTurn()
|
||||
|
||||
func _PvPTurn():
|
||||
Mes("你的手牌:%s" % _HandStr(playerHand))
|
||||
if _HandValue(playerHand) == 21:
|
||||
Mes("21 点!")
|
||||
_PvPStand()
|
||||
else:
|
||||
Choice("要牌", _PvPHit)
|
||||
Choice("停牌", _PvPStand)
|
||||
|
||||
func _PvPHit():
|
||||
var card : int = npc.ownScript.call("DrawCard", own)
|
||||
if card < 0:
|
||||
_PvPStand()
|
||||
return
|
||||
playerHand.append(card)
|
||||
var value : int = _HandValue(playerHand)
|
||||
if value > 21:
|
||||
Mes("你的手牌:%s" % _HandStr(playerHand))
|
||||
Mes("爆牌!刚才心里那点犹豫,其实已经给过你提醒了。")
|
||||
npc.ownScript.call("FinishHand", own, value, true)
|
||||
_PvPWait()
|
||||
elif value == 21:
|
||||
Mes("你的手牌:%s" % _HandStr(playerHand))
|
||||
_PvPStand()
|
||||
else:
|
||||
_PvPTurn()
|
||||
|
||||
func _PvPStand():
|
||||
npc.ownScript.call("FinishHand", own, _HandValue(playerHand), false)
|
||||
_PvPWait()
|
||||
|
||||
func _PvPWait():
|
||||
var game : Dictionary = npc.ownScript.call("GetGame", own)
|
||||
if game.has("result"):
|
||||
_PvPShowResult(game)
|
||||
else:
|
||||
Mes("你这边结束了。现在等对手做决定。")
|
||||
Choice("查看", _PvPWaitCheck)
|
||||
Choice("认输", _PvPForfeit)
|
||||
|
||||
func _PvPWaitCheck():
|
||||
var game : Dictionary = npc.ownScript.call("GetGame", own)
|
||||
if game.has("result"):
|
||||
_PvPShowResult(game)
|
||||
else:
|
||||
Mes("还在思考。谨慎的人值得尊重,除非他只是忘了轮到自己。")
|
||||
Choice("查看", _PvPWaitCheck)
|
||||
Choice("认输", _PvPForfeit)
|
||||
|
||||
func _PvPShowResult(game : Dictionary):
|
||||
var isP1 : bool = game.get("p1") == own
|
||||
var myVal : int = game.get("p1Value") if isP1 else game.get("p2Value")
|
||||
var oppBust : bool = game.get("p2Busted") if isP1 else game.get("p1Busted")
|
||||
var oppHand : Array = game.get("p2Hand") if isP1 else game.get("p1Hand")
|
||||
var myBust : bool = game.get("p1Busted") if isP1 else game.get("p2Busted")
|
||||
Mes("你的点数:%d%s" % [myVal, "(爆牌)" if myBust else ""])
|
||||
Mes("对手手牌:%s%s" % [_HandStr(oppHand), "(爆牌)" if oppBust else ""])
|
||||
var result : String = game.get("result", "")
|
||||
if result == "draw":
|
||||
Mes("平局!势均力敌,这在我的桌上不常见。")
|
||||
elif (result == "p1" and isP1) or (result == "p2" and not isP1):
|
||||
Mes("胜利归你!今天牌也站在你这边。")
|
||||
else:
|
||||
Mes("可惜。牌有自己的脾气,但它总会再绕回来。")
|
||||
npc.ownScript.call("CleanupGame", own)
|
||||
Choice("再来一局", StartPvP)
|
||||
Choice("离开", Decline)
|
||||
|
||||
func _PvPForfeit():
|
||||
npc.ownScript.call("ForfeitPvP", own)
|
||||
Mes("中途离桌?放在我年轻时,这至少要请全桌喝一轮。")
|
||||
Choice("再来一局", StartPvP)
|
||||
Choice("离开", Decline)
|
||||
Reference in New Issue
Block a user