feat: add get game winner logic
This commit is contained in:
parent
f3a22876dc
commit
03977ecd64
1 changed files with 62 additions and 29 deletions
|
@ -35,13 +35,14 @@ const (
|
|||
// STRUCTS
|
||||
|
||||
type Room struct {
|
||||
Id string
|
||||
Host interop.Hash160
|
||||
Status string
|
||||
PrizePool int
|
||||
CountWinners int
|
||||
Players []Player
|
||||
Rounds []Round
|
||||
Id string
|
||||
Host interop.Hash160
|
||||
Status string
|
||||
PrizePool int
|
||||
RoundWinnersCount int
|
||||
GameWinnersCount int
|
||||
Players []Player
|
||||
Rounds []Round
|
||||
}
|
||||
|
||||
type Round struct {
|
||||
|
@ -93,17 +94,18 @@ func sendMessageToPlayer(message string, player Player) {
|
|||
|
||||
// MAIN METHODS TO PLAY IN GAME
|
||||
|
||||
func CreateRoom(host interop.Hash160, countWinners int) string {
|
||||
func CreateRoom(host interop.Hash160, RoundWinnersCount, GameWinnersCount int) string {
|
||||
var ctx = storage.GetContext()
|
||||
var id = uuid.NewString()
|
||||
var room = Room{
|
||||
Id: id,
|
||||
Host: host,
|
||||
Status: RoomStatusWaiting,
|
||||
PrizePool: 0,
|
||||
CountWinners: countWinners,
|
||||
Players: []Player{},
|
||||
Rounds: []Round{},
|
||||
Id: id,
|
||||
Host: host,
|
||||
Status: RoomStatusWaiting,
|
||||
PrizePool: 0,
|
||||
RoundWinnersCount: RoundWinnersCount,
|
||||
GameWinnersCount: GameWinnersCount,
|
||||
Players: []Player{},
|
||||
Rounds: []Round{},
|
||||
}
|
||||
|
||||
// todo: Добавить списание токенов за создание комнаты
|
||||
|
@ -164,7 +166,7 @@ func StartGame(roomId string) bool {
|
|||
var ctx = storage.GetContext()
|
||||
var room = getRoom(ctx, roomId)
|
||||
|
||||
if !room.Host.Equals(getSender()) || room.Status != RoomStatusWaiting || len(room.Players) <= room.CountWinners {
|
||||
if !room.Host.Equals(getSender()) || room.Status != RoomStatusWaiting || len(room.Players) <= room.RoundWinnersCount {
|
||||
return false // Only host can start game, room status must be waiting and players count must be > count winners
|
||||
}
|
||||
|
||||
|
@ -294,30 +296,30 @@ func VoteAnswer(roomId string, answerIdx int) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func chooseWonAnswers(round Round, countWinners int) []Answer {
|
||||
func chooseWonAnswers(round Round, RoundWinnersCount int) []Answer {
|
||||
var wonAnswers []Answer
|
||||
var answers = round.Answers
|
||||
sort.Slice(answers, func(a, b int) bool {
|
||||
return len(answers[a].Votes) > len(answers[b].Votes)
|
||||
})
|
||||
|
||||
if countWinners > len(round.Answers) {
|
||||
if RoundWinnersCount > len(round.Answers) {
|
||||
return round.Answers
|
||||
}
|
||||
|
||||
if countWinners == 1 {
|
||||
if RoundWinnersCount == 1 {
|
||||
return []Answer{answers[0]}
|
||||
}
|
||||
|
||||
// Choose wonAnswers from sorted answers. If the current answer has the same number of votes as the previous one,
|
||||
// we add it to the wonAnswers list. We increase the number of wonAnswers if there are multiple answers with the same
|
||||
// number of votes, as in cases where there are 5 answers with equal votes and countWinners is 3, all should be included.
|
||||
// number of votes, as in cases where there are 5 answers with equal votes and RoundWinnersCount is 3, all should be included.
|
||||
var lastVote = len(answers[0].Votes)
|
||||
wonAnswers = append(wonAnswers, answers[0])
|
||||
for i := 1; i < len(answers) && len(wonAnswers) < countWinners; i++ {
|
||||
for i := 1; i < len(answers) && len(wonAnswers) < RoundWinnersCount; i++ {
|
||||
var currentVote = len(answers[i].Votes)
|
||||
if lastVote == currentVote {
|
||||
countWinners++ // todo: Могут возникнуть проблемы, надо протестировать
|
||||
RoundWinnersCount++ // todo: Могут возникнуть проблемы, надо протестировать
|
||||
}
|
||||
lastVote = currentVote
|
||||
wonAnswers = append(wonAnswers, answers[i])
|
||||
|
@ -326,7 +328,8 @@ func chooseWonAnswers(round Round, countWinners int) []Answer {
|
|||
return wonAnswers
|
||||
}
|
||||
|
||||
// GetRoundWinner todo: Нам сказали, что ссылку на другой контракт нельзя чисто, используем nns
|
||||
// GetRoundWinner todo(-): Нам сказали, что ссылку на другой контракт нельзя чисто, используем nns
|
||||
// GetRoundWinner todo: Разные реализации распределения наград можно реализовать в контракте с деньгами
|
||||
func GetRoundWinner(roomId string) bool {
|
||||
var ctx = storage.GetContext()
|
||||
var room = getRoom(ctx, roomId)
|
||||
|
@ -340,7 +343,7 @@ func GetRoundWinner(roomId string) bool {
|
|||
return false // Zero winners, because no answer
|
||||
}
|
||||
|
||||
var wonAnswers = chooseWonAnswers(round, room.CountWinners)
|
||||
var wonAnswers = chooseWonAnswers(round, room.RoundWinnersCount)
|
||||
var players = room.Players
|
||||
for _, answer := range wonAnswers {
|
||||
for _, player := range players {
|
||||
|
@ -354,7 +357,7 @@ func GetRoundWinner(roomId string) bool {
|
|||
|
||||
var result string
|
||||
for i, answer := range wonAnswers {
|
||||
result += fmt.Sprintf("place:%d, winner:%s, votes:%s", i, answer.Wallet, answer.Votes)
|
||||
result += fmt.Sprintf("place:%d, winner:%s, votes:%s\n", i, answer.Wallet, answer.Votes)
|
||||
}
|
||||
|
||||
for _, player := range room.Players {
|
||||
|
@ -373,8 +376,6 @@ func automaticFinishGame(ctx storage.Context, room *Room, voted int) bool {
|
|||
return false // All players must have voted to finish the game
|
||||
}
|
||||
|
||||
// todo: Раз это завершение игры может произойти не в промежуточную фазу между раундами, надо подумать, что делать с наградами
|
||||
// наверное последний раунд обрывать и определять победителя по предыдущим (как и обычно)
|
||||
return finishGame(ctx, room)
|
||||
}
|
||||
|
||||
|
@ -424,8 +425,8 @@ func ManuallyFinishGame(roomId string) bool {
|
|||
}
|
||||
|
||||
func finishGame(ctx storage.Context, room *Room) bool {
|
||||
// todo: Определение победителя игры
|
||||
|
||||
var winners = getGameWinner(room)
|
||||
|
||||
// todo: Отправка награды победителям и хосту
|
||||
|
||||
// todo: Нотификация результатов всей игры
|
||||
|
@ -435,6 +436,38 @@ func finishGame(ctx storage.Context, room *Room) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
// todo: @vr61v /check
|
||||
func getGameWinner(room *Room) []Player {
|
||||
var players = room.Players
|
||||
var winners []Player
|
||||
var GameWinnersCount = room.GameWinnersCount
|
||||
|
||||
sort.Slice(players, func(a, b int) bool {
|
||||
return players[a].RoundsWon > players[b].RoundsWon
|
||||
})
|
||||
|
||||
if GameWinnersCount > len(room.Players) {
|
||||
return room.Players
|
||||
}
|
||||
|
||||
if GameWinnersCount == 1 {
|
||||
return []Player{players[0]}
|
||||
}
|
||||
|
||||
var lastWinner = players[0].RoundsWon
|
||||
winners = append(winners, players[0])
|
||||
for i := 1; i < len(players) && len(winners) < GameWinnersCount; i++ {
|
||||
var currentVote = players[i].RoundsWon
|
||||
if lastWinner == currentVote {
|
||||
GameWinnersCount++ // todo: Могут возникнуть проблемы, надо протестировать
|
||||
}
|
||||
lastWinner = currentVote
|
||||
winners = append(winners, players[i])
|
||||
}
|
||||
|
||||
return winners
|
||||
}
|
||||
|
||||
/* todo: Логика выкидывания игрока из игры, если пропускает несколько вопросов подряд -
|
||||
* делаем булевый флаг по которому определяем, активен игрок или нет.
|
||||
*/
|
||||
|
|
Loading…
Add table
Reference in a new issue