diff --git a/contracts/room_contract.go b/contracts/room_contract.go index 5d0c1e2..b317ab1 100644 --- a/contracts/room_contract.go +++ b/contracts/room_contract.go @@ -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: Логика выкидывания игрока из игры, если пропускает несколько вопросов подряд - * делаем булевый флаг по которому определяем, активен игрок или нет. */