Skip to content

Commit

Permalink
提名投票bug
Browse files Browse the repository at this point in the history
  • Loading branch information
liuzhaomax committed Mar 18, 2024
1 parent e8cf5d0 commit df5e30d
Show file tree
Hide file tree
Showing 9 changed files with 63 additions and 56 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
+ 邪恶
1. 圣徒被投票处决,且未中毒
2. 平民阵营被屠城
3. 活人数小于等于4,平民可投的票数不大于活人的半数(向上取整),且存活的邪恶玩家数量不小于活人的半数(向上取整),且没有杀手或有杀手没有子弹,且没有市长或市长已死或酒鬼市长
3. 活人数小于等于4,未发生爪牙转化为恶魔,平民可投的票数不大于活人的半数(向上取整),且存活的邪恶玩家数量不小于活人的半数(向上取整),且没有杀手或有杀手没有子弹,且没有市长或市长已死或酒鬼市长
+ 与无辅助器的不同之处
+ 没有说书人
+ 全程不需闭眼
Expand Down
34 changes: 17 additions & 17 deletions client/src/pages/gaming/Gaming.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ function Gaming() {
}
socket.onmessage = function(event) {
// TODO 内测用,记得关闭
// console.log("Received message from server:", JSON.parse(event.data))
console.log("Received message from server:", JSON.parse(event.data))
setGame(JSON.parse(event.data))
}
socket.onerror = function(error) {
Expand Down Expand Up @@ -212,14 +212,14 @@ function Gaming() {
let me = getMe(game)
// 当前玩家死亡,他不能提名,不能施法,则他看其他死了的玩家就是加灰色不能选择
// 当前玩家没死,他就不可能看到灰色
if (me.state.dead) {
for (let i = 0; i < game.players.length; i++) {
if (game.players[i].state.dead) {
let seat = document.getElementById(game.players[i].id)
if (!seat.classList.contains("highlight-dead")) {
seat.classList.add("highlight-dead")
seat.classList.add("highlight-dead-cant-be-selected")
}
for (let i = 0; i < game.players.length; i++) {
if (game.players[i].state.dead) {
let seat = document.getElementById(game.players[i].id)
if (!seat.classList.contains("highlight-dead")) {
seat.classList.add("highlight-dead")
}
if (me.state.dead && !seat.classList.contains("highlight-dead-cant-be-selected")) {
seat.classList.add("highlight-dead-cant-be-selected")
}
}
}
Expand All @@ -234,9 +234,9 @@ function Gaming() {
for (let i = 0; i < game.players.length; i++) {
// 投票标签
tagTou = document.getElementById(game.players[i].id + "-tou")
if (game.players[i].ready.vote > 0 && tagTou.classList.contains("tag-hidden")) {
if (game.players[i].ready.vote && tagTou.classList.contains("tag-hidden")) {
tagTou.classList.remove("tag-hidden")
} else if (game.players[i].ready.vote === 0 && !tagTou.classList.contains("tag-hidden")) {
} else if (!game.players[i].ready.vote && !tagTou.classList.contains("tag-hidden")) {
tagTou.classList.add("tag-hidden")
if (game.players[i].state.master) {
butlerTou = true
Expand Down Expand Up @@ -526,7 +526,7 @@ function Gaming() {
let me = getMe(game)
if (me.ready.vote && game.state.votingStep && game.state.stage !== 0) {
for (let j = 0; j < game.players.length; j++) {
if (game.players[j].state.nominated) {
if (game.nominated) {
emitVote()
break
}
Expand Down Expand Up @@ -646,15 +646,15 @@ function Gaming() {
return "本局未开始,不能投票"
}
if (!me.ready.vote) {
return "您本阶段已投过票"
return "您已不能投票"
}
if (!game.state.votingStep) {
return "不在投票处决环节不能投票"
}
if (me.ready.vote > 0 && game.state.votingStep) {
if (me.ready.vote && game.state.votingStep) {
let content = "你确定要投票给玩家 "
for (let j = 0; j < game.players.length; j++) {
if (game.players[j].state.nominated) {
if (game.nominated) {
content += "<" + game.players[j].name + "> "
break
}
Expand All @@ -673,7 +673,7 @@ function Gaming() {
if (me.state.dead) {
return "您已死亡"
}
if (game.state.votingStep) {
if (game.state.votingStep && me.character !== "杀手") {
return "投票阶段不能发动技能"
}
let selectedPlayersObj = []
Expand Down Expand Up @@ -956,7 +956,7 @@ function Gaming() {
closable={false}
onClose={onClose}
open={open}
key="top"
key="instruction"
>
<Instruction/>
</Drawer>
Expand Down
2 changes: 1 addition & 1 deletion client/src/pages/gaming/Instruction.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const text = `
+ 邪恶
1. 圣徒被投票处决,且未中毒
2. 平民阵营被屠城
3. 活人数小于等于4,平民可投的票数不大于活人的半数(向上取整),且存活的邪恶玩家数量不小于活人的半数(向上取整),且没有杀手或有杀手没有子弹,且没有市长或市长已死或酒鬼市长
3. 活人数小于等于4,未发生爪牙转化为恶魔,平民可投的票数不大于活人的半数(向上取整),且存活的邪恶玩家数量不小于活人的半数(向上取整),且没有杀手或有杀手没有子弹,且没有市长或市长已死或酒鬼市长
+ 与无辅助器的不同之处
+ 没有说书人
+ 全程不需闭眼
Expand Down
4 changes: 2 additions & 2 deletions client/src/pages/room/Room.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ function Room() {
closable={false}
onClose={onCloseInstruction}
open={openInstruction}
key="top"
key="instruction"
>
<Instruction/>
</Drawer>
Expand All @@ -204,7 +204,7 @@ function Room() {
closable={false}
onClose={onCloseUpdateLog}
open={openUpdateLog}
key="top"
key="updateLog"
>
<UpdateLog/>
</Drawer>
Expand Down
27 changes: 17 additions & 10 deletions server/handler/checkout.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,23 +170,26 @@ func checkoutNight(mux *sync.Mutex, game *model.Room) {
// 生成随机信息
for {
randInt := rand.Intn(len(game.Players))
if (game.Players[randInt].CharacterType == Outsiders || game.Players[randInt].State.Drunk) &&
game.Players[randInt].Id != player.Id && game.Players[randInt].Character != Recluse &&
game.Players[randInt].Character != Spy {
if game.Players[randInt].CharacterType == Outsiders && game.Players[randInt].Id != player.Id &&
game.Players[randInt].Character != Recluse && game.Players[randInt].Character != Spy {
outsider = game.Players[randInt]
character = game.Players[randInt].Character
break
}
// 如果是酒鬼被选中
if game.Players[randInt].State.Drunk && game.Players[randInt].Id != player.Id &&
game.Players[randInt].Character != Recluse && game.Players[randInt].Character != Spy {
outsider = game.Players[randInt]
character = Drunk
break
}
// 如果间谍被选中
if game.Players[randInt].Character == Spy && game.Players[randInt].State.RegisteredAsType == Outsiders {
outsider = game.Players[randInt]
character = game.Players[randInt].State.RegardedAs
break
}
}
// 如果是酒鬼被选中
if outsider.CharacterType != Outsiders {
character = Drunk
}
for {
randInt := rand.Intn(len(game.Players))
if game.Players[randInt].Id != outsider.Id && game.Players[randInt].Id != player.Id {
Expand Down Expand Up @@ -781,7 +784,7 @@ func checkoutNight(mux *sync.Mutex, game *model.Room) {
msgAll = ""
// 拼接日志
msgAll += fmt.Sprintf("[%s] ", fromPlayer.Name)
info := fmt.Sprintf("认定 [%s] 为主人,他投你可选投,他不投你也不能投\n", game.Players[toPlayerIndexSlice[0]].Name)
info := fmt.Sprintf("认定 [%s] 为主人,他投你可选投,他不投你票无效\n", game.Players[toPlayerIndexSlice[0]].Name)
msgPlayer += info
msgAll += info
game.Players[fromPlayer.Index].Log += msgPlayer
Expand Down Expand Up @@ -840,6 +843,7 @@ func checkout(game *model.Room, executed *model.Player) {
var mayorAlive bool // 市长是否存活
var scarletWomanAlive bool // 魅魔是否存活
var poisonerAlive bool // 下毒者是否存活
var demonCount int // 恶魔数量(不论死活)
for _, player := range game.Players {
// 对应平民胜利条件1
if player.CharacterType == Demons && !player.State.Dead {
Expand Down Expand Up @@ -870,6 +874,9 @@ func checkout(game *model.Room, executed *model.Player) {
if !player.State.Dead && (player.CharacterType == Demons || player.CharacterType == Minions) {
evilAliveCount++
}
if player.CharacterType == Demons {
demonCount++
}
}
// 平民胜利条件1(恶魔受不了了自杀情况),这里有三种铲除恶魔的可能:1、杀手,2、处决,3、自刀。
// 处决在结算投票时判定,枪杀在枪手施法后判定,自刀在判定刀人时判定,所以realDemonCount不可能为0
Expand Down Expand Up @@ -899,8 +906,8 @@ func checkout(game *model.Room, executed *model.Player) {
}
// 邪恶胜利条件3
halfAlive := int(math.Ceil(float64(aliveCount / 2)))
if game.Result == "" && aliveCount <= 4 && canVote-evilAliveCount <= halfAlive && evilAliveCount >= halfAlive && !hasSlayerBullet && !mayorAlive {
msg += "达成邪恶胜利条件三:活人数小于等于4,平民可投的票数不大于活人的半数(向上取整),且存活的邪恶玩家数量不小于活人的半数(向上取整),且没有杀手或有杀手没有子弹,且没有市长或市长已死或酒鬼市长\n"
if game.Result == "" && aliveCount <= 4 && demonCount == 1 && canVote-evilAliveCount <= halfAlive && evilAliveCount >= halfAlive && !hasSlayerBullet && !mayorAlive {
msg += "达成邪恶胜利条件三:活人数小于等于4,未发生爪牙转化为恶魔,平民可投的票数不大于活人的半数(向上取整),且存活的邪恶玩家数量不小于活人的半数(向上取整),且没有杀手或有杀手没有子弹,且没有市长或市长已死或酒鬼市长\n"
msg += "本局结束,邪恶胜利\n"
game.Result = "邪恶阵营胜利"
}
Expand Down
30 changes: 10 additions & 20 deletions server/handler/execute.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,7 @@ func execute(game *model.Room) {
game.Players[i].Log += msg
}
game.Log += msg
// 发送日志
broadcast(game)

// 判断圣徒 - 邪恶胜利条件4
if game.Executed != nil && game.Executed.Character == Saint && !game.Executed.State.Poisoned {
checkout(game, game.Executed)
}
// 判断魅魔 - 有人被处决,处决的人是小恶魔,活人大于等于5个,有魅魔且没死
var aliveCount int // 活人数量
var scarletWomanIndex = -1
Expand Down Expand Up @@ -58,22 +52,17 @@ func execute(game *model.Room) {
emit(game, scarletWoman.Id)
}

// 处决结束,清空票池,这里只复位和提名投票有关的状态,技能影响状态在toggleNight复位
game.VoteLogs = map[string]string{}
game.VotePool = map[string]int{}
game.Nominated = nil
game.Executed = nil
for i := range game.Players {
game.Players[i].State.VotedFromButler = false
game.Players[i].State.VotedFromMaster = false
}
// 发送votingStep
// 发送日志
broadcast(game)
// 立即结算
checkout(game, game.Executed)
}

func findExecutee(game *model.Room) (*model.Player, int) {
// 被圣女弹死
if game.Executed != nil {
return game.Executed, 0
}
// 无人被提名
if len(game.VotePool) == 0 {
return nil, 0
Expand All @@ -84,18 +73,19 @@ func findExecutee(game *model.Room) (*model.Player, int) {
aliveCount++
}
}
var halfAliveCount = int(math.Ceil(float64(aliveCount / 2)))
var halfAliveCount = int(math.Ceil(float64(aliveCount) / 2))
var executeeId string
var executeeVoteCount int
var isHighestRepeated bool
for nominatedId, voteCount := range game.VotePool {
if voteCount >= halfAliveCount && voteCount == executeeVoteCount {
isHighestRepeated = true
continue
}
if voteCount >= halfAliveCount && voteCount > executeeVoteCount {
executeeId = nominatedId
executeeVoteCount = voteCount
}
if voteCount >= halfAliveCount && voteCount == executeeVoteCount {
isHighestRepeated = true
}
}
if executeeId != "" && !isHighestRepeated {
for i, player := range game.Players {
Expand Down
3 changes: 3 additions & 0 deletions server/handler/game.go
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,9 @@ func initStatus(players []model.Player, replaceDrunk string) []model.Player {
players[i].CharacterType = Townsfolk
players[i].Character = replaceDrunk
players[i].State.Drunk = true
if replaceDrunk == Slayer {
players[i].State.Bullet = true
}
case FortuneTeller:
for {
randIdx := rand.Intn(len(players))
Expand Down
13 changes: 10 additions & 3 deletions server/handler/toggleNight.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,15 @@ func toggleNight(mux *sync.Mutex, game *model.Room) {
} else {
game.State.Day += 1
msg = fmt.Sprintf("第%d天,天亮了~\n", game.State.Day+1)
// 天亮 清空executed
// 天亮 清空executed,和其他与投票提名相关的状态
game.VoteLogs = map[string]string{}
game.VotePool = map[string]int{}
game.Nominated = nil
game.Executed = nil
for i := range game.Players {
game.Players[i].State.VotedFromButler = false
game.Players[i].State.VotedFromMaster = false
}
}
// 存入总日志
game.Log += msg
Expand All @@ -59,11 +66,11 @@ func toggleNight(mux *sync.Mutex, game *model.Room) {
game.State.Night = !game.State.Night

for i := range game.Players {
// 活人调整状态 - 让所有活人重新可以投票,夜转日结算,没投票还有票
// 活人调整状态 - 夜转日结算,没死可以再提名
if !game.Players[i].State.Dead {
game.Players[i].Ready.Nominate = true
game.Players[i].Ready.Nominated = true
}
game.Players[i].Ready.Nominated = true
// 调整玩家施放技能的准备状态
game.Players[i].State.Casted = true
game.CastPool = map[string][]string{}
Expand Down
4 changes: 2 additions & 2 deletions server/handler/vote.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@ func vote(mux *sync.Mutex, game *model.Room, playerId string) {
// 管家的投票在endVoting结算
if game.Players[i].Character != Butler {
msgAll += fmt.Sprintf("投票 [%s] 成功\n", game.Nominated.Name)
// 总日志加入票池
game.VoteLogs[game.Nominated.Id] += msgAll
}
if game.Players[i].Character == Butler {
game.Nominated.State.VotedFromButler = true
}
if game.Players[i].State.Master {
game.Nominated.State.VotedFromMaster = true
}
// 总日志加入票池
game.VoteLogs[game.Nominated.Id] += msgAll
// 发送个人日志
emit(game, playerId)
break
Expand Down

0 comments on commit df5e30d

Please sign in to comment.