diff --git a/contracts/main.go b/contracts/room_contract.go similarity index 79% rename from contracts/main.go rename to contracts/room_contract.go index ca9caac..7c7824b 100644 --- a/contracts/main.go +++ b/contracts/room_contract.go @@ -23,11 +23,11 @@ func RuntimeNotify(args []any) { } const ( - RoomStatusWaiting = "waiting" // Waiting for the game to start, players are joining - RoomStatusGaming = "gaming" // In this phase, players are ready, but the question hasn't been asked yet - RoomStatusRoundIsStarted = "round_is_started" // Phase when the round has started and the question has been asked, players can submit answers - RoomStatusVoting = "voting" // Voting phase, where players select the best answer from the options. - RoomStatusFinished = "finished" // Game is finished, and results have been determined. + RoomStatusWaiting = "waiting" // Waiting for the game to start, players are joining + RoomStatusGaming = "gaming" // In this phase, players are ready, but the question hasn't been asked yet + RoomStatusAnswering = "answering" // Phase when the round has started and the question has been asked, players can submit answers + RoomStatusVoting = "voting" // Voting phase, where players select the best answer from the options + RoomStatusFinished = "finished" // Game is finished, and results have been determined ) type Room struct { @@ -35,22 +35,20 @@ type Room struct { Host interop.Hash160 Status string PrizePool int - CountWinners int // ??? + CountWinners int Players []Player Rounds []Round } type Round struct { - number int // Sequence number of round question string answers []Answer } type Answer struct { - wallet interop.Hash160 - content string - votes []interop.Hash160 // Wallets who voted for answer - answerIdx int // Index of sent content to user + wallet interop.Hash160 + content string + votes []interop.Hash160 // Wallets who voted for answer } type Player struct { @@ -215,39 +213,19 @@ func AskQuestion(roomId string, question string) bool { return false // Only host can ask question, room status must be game is started } - newRound := Round{ - number: len(room.Rounds) + 1, + var round = Round{ question: question, answers: []Answer{}, } - room.Rounds = append(room.Rounds, newRound) + room.Rounds = append(room.Rounds, round) + room.Status = RoomStatusAnswering - // todo: Списание средств за создание вопроса ? Надо ли делать вообще или можно оставить бесплатным - - // todo: Можно наверное склеить с StartQuestion, потому что после его создания можно сразу же начать раунд - // грубо говоря вынести ask в приватный как createQuestion и использовать его в StartQuestion, переименовав - // его в ask - - setRoom(ctx, &room) - return true -} - -func StartQuestion(roomId string) bool { - var ctx = storage.GetContext() - var room = getRoom(ctx, roomId) - - if !room.Host.Equals(getSender()) || room.Status != RoomStatusGaming { - return false // Only host can start question, room status must be game is started - } - - room.Status = RoomStatusRoundIsStarted - - var question = room.Rounds[len(room.Rounds)-1].question for _, player := range room.Players { sendMessageToPlayer(question, player) } // todo: Не забыть про ннс + // todo: Добавить списание токенов за создание вопроса setRoom(ctx, &room) return true @@ -256,22 +234,27 @@ func StartQuestion(roomId string) bool { func SendAnswer(roomId string, text string) bool { var ctx = storage.GetContext() var room = getRoom(ctx, roomId) + var wallet = getSender() - if !roomContainsPlayer(room.Players, getSender()) || room.Status != RoomStatusRoundIsStarted { + if !roomContainsPlayer(room.Players, getSender()) || room.Status != RoomStatusAnswering { return false // Only player can send content, room status must be round is started } // todo: Добавить списание токенов за добавление ответа var round = room.Rounds[len(room.Rounds)-1] - answer := Answer{ - wallet: getSender(), - content: text, - votes: []interop.Hash160{}, - answerIdx: len(round.answers), + + for _, answer := range round.answers { + if answer.wallet.Equals(wallet) { + return false // Player cannot send answer twice + } } - // todo: Проверка отправки ответа (от каждого участника если отправлен ответ, то макс один) + answer := Answer{ + wallet: wallet, + content: text, + votes: []interop.Hash160{}, + } round.answers = append(round.answers, answer) @@ -284,8 +267,8 @@ func EndQuestion(roomId string) bool { var ctx = storage.GetContext() var room = getRoom(ctx, roomId) - if !room.Host.Equals(getSender()) || room.Status != RoomStatusRoundIsStarted { - return false // Only host can end question, room status must be round is started + if !room.Host.Equals(getSender()) || room.Status != RoomStatusAnswering { + return false // Only host can end question, room status must be answering } room.Status = RoomStatusVoting @@ -329,8 +312,7 @@ func VoteAnswer(roomId string, answerIdx int) bool { return true } -// todo (-): Можно прям сюда подсовывать ссылку на другой контракт кастомный и дефолт реализацию оставить в методе, а кастомную условием -// todo: Нам сказали, что ссылку на другой контракт нельзя чисто, используем nns +// GetWinner todo: Нам сказали, что ссылку на другой контракт нельзя чисто, используем nns func GetWinner(roomId string) bool { var ctx = storage.GetContext() var room = getRoom(ctx, roomId)