<commit_before>package nugugame

import (
	"fmt"
	"math/rand"
	"regexp"
	"sort"
	"strings"
	"sync"
	"time"

	"github.com/globalsign/mgo/bson"

	"github.com/Seklfreak/Robyul2/cache"
	"github.com/Seklfreak/Robyul2/helpers"
	"github.com/Seklfreak/Robyul2/modules/plugins/idols"
	"github.com/bwmarrin/discordgo"
)

const (
	NUGUGAME_IMAGE_RESIZE_HEIGHT = 200
	NUGUGAME_DEFULT_ROUND_DELAY  = 12
	NUGUGAME_ROUND_DELETE_DELAY  = 2 * time.Second
	CHECKMARK_EMOJI              = "✅"
	SINGLE_NUGUGAME_CACHE_KEY    = "currentSingleNugugames"
	MULTI_NUGUGAME_CACHE_KEY     = "currentMultiNugugames"
)

var currentNuguGames map[string]*nuguGame
var currentNuguGamesMutex sync.RWMutex
var alphaNumericRegex *regexp.Regexp

// startNuguGame Starts a new nugu game or resumes a game in cache
func startNuguGame(msg *discordgo.Message, commandArgs []string) {

	// if the user already has a game, do nothing
	if game := getNuguGameByUserID(msg.Author.ID); game != nil {
		helpers.SendMessage(msg.ChannelID, "You already have a current nugu game running, you must finish it before starting a new one.")
		return
	}

	// if the channel already has a game, do nothing
	if game := getNuguGamesByChannelID(msg.ChannelID); game != nil {
		helpers.SendMessage(msg.ChannelID, "Only one running nugu game is allowed per channel.")
		return
	}

	// default game settings
	gameGender := "mixed"
	isMulti := false
	gameType := "idol"
	gameDifficulty := "medium"
	lives := 3

	// validate game arguments and adjust game settings as needed
	if len(commandArgs) > 0 {
		for _, arg := range commandArgs {

			if gender, ok := gameGenders[arg]; ok == true {
				gameGender = gender
				continue
			}

			if arg == "multi" {
				isMulti = true
				continue
			}

			if arg == "group" {
				gameType = "group"
				continue
			}

			if _, ok := idolsByDifficulty[arg]; ok {
				gameDifficulty = arg
				lives = difficultyLives[arg]
				continue
			}

			// if a arg was passed that didn't match any check, send invalid args message
			helpers.SendMessage(msg.ChannelID, helpers.GetText("bot.arguments.invalid"))
			return
		}
	}

	var game *nuguGame

	// check if a cached game exists
	if isMulti {
		game = getCachedMultiGame(msg.ChannelID)
	} else {
		game = getCachedSingleGame(msg.Author.ID)
	}

	// check if the user has a cached game, if not then make a new one based on their options
	if game == nil {
		game = &nuguGame{
			Gender:          gameGender,
			WaitingForGuess: false,
			IsMultigame:     isMulti,
			GameType:        gameType,
			Difficulty:      gameDifficulty,
			LivesRemaining:  lives,
		}
	}

	game.ChannelID = msg.ChannelID
	game.User = msg.Author
	game.GuessChannel = make(chan *discordgo.Message)
	game.GuessTimeoutTimer = time.NewTimer(NUGUGAME_DEFULT_ROUND_DELAY * time.Second)
	game.UsersCorrectGuesses = make(map[string][]bson.ObjectId)

	game.saveGame()
	game.sendRound()
	game.watchForGuesses()
}

// sendRound sends the next round in the game
func (g *nuguGame) sendRound() {
	if g.WaitingForGuess == true {
		return
	}

	// delete last round message if there was one.<commit_msg>[nugugame] fixes multi games restoring from cache losing individual user scores<commit_after>package nugugame

import (
	"fmt"
	"math/rand"
	"regexp"
	"sort"
	"strings"
	"sync"
	"time"

	"github.com/globalsign/mgo/bson"

	"github.com/Seklfreak/Robyul2/cache"
	"github.com/Seklfreak/Robyul2/helpers"
	"github.com/Seklfreak/Robyul2/modules/plugins/idols"
	"github.com/bwmarrin/discordgo"
)

const (
	NUGUGAME_IMAGE_RESIZE_HEIGHT = 200
	NUGUGAME_DEFULT_ROUND_DELAY  = 12
	NUGUGAME_ROUND_DELETE_DELAY  = 2 * time.Second
	CHECKMARK_EMOJI              = "✅"
	SINGLE_NUGUGAME_CACHE_KEY    = "currentSingleNugugames"
	MULTI_NUGUGAME_CACHE_KEY     = "currentMultiNugugames"
)

var currentNuguGames map[string]*nuguGame
var currentNuguGamesMutex sync.RWMutex
var alphaNumericRegex *regexp.Regexp

// startNuguGame Starts a new nugu game or resumes a game in cache
func startNuguGame(msg *discordgo.Message, commandArgs []string) {

	// if the user already has a game, do nothing
	if game := getNuguGameByUserID(msg.Author.ID); game != nil {
		helpers.SendMessage(msg.ChannelID, "You already have a current nugu game running, you must finish it before starting a new one.")
		return
	}

	// if the channel already has a game, do nothing
	if game := getNuguGamesByChannelID(msg.ChannelID); game != nil {
		helpers.SendMessage(msg.ChannelID, "Only one running nugu game is allowed per channel.")
		return
	}

	// default game settings
	gameGender := "mixed"
	isMulti := false
	gameType := "idol"
	gameDifficulty := "medium"
	lives := 3

	// validate game arguments and adjust game settings as needed
	if len(commandArgs) > 0 {
		for _, arg := range commandArgs {

			if gender, ok := gameGenders[arg]; ok == true {
				gameGender = gender
				continue
			}

			if arg == "multi" {
				isMulti = true
				continue
			}

			if arg == "group" {
				gameType = "group"
				continue
			}

			if _, ok := idolsByDifficulty[arg]; ok {
				gameDifficulty = arg
				lives = difficultyLives[arg]
				continue
			}

			// if a arg was passed that didn't match any check, send invalid args message
			helpers.SendMessage(msg.ChannelID, helpers.GetText("bot.arguments.invalid"))
			return
		}
	}

	var game *nuguGame

	// check if a cached game exists
	if isMulti {
		game = getCachedMultiGame(msg.ChannelID)
	} else {
		game = getCachedSingleGame(msg.Author.ID)
	}

	// check if the user has a cached game, if not then make a new one based on their options
	if game == nil {
		game = &nuguGame{
			Gender:          gameGender,
			WaitingForGuess: false,
			IsMultigame:     isMulti,
			GameType:        gameType,
			Difficulty:      gameDifficulty,
			LivesRemaining:  lives,
		}
	}

	game.ChannelID = msg.ChannelID
	game.User = msg.Author
	game.GuessChannel = make(chan *discordgo.Message)
	game.GuessTimeoutTimer = time.NewTimer(NUGUGAME_DEFULT_ROUND_DELAY * time.Second)

	if game.UsersCorrectGuesses == nil {
		game.UsersCorrectGuesses = make(map[string][]bson.ObjectId)
	}

	game.saveGame()
	game.sendRound()
	game.watchForGuesses()
}

// sendRound sends the next round in the game
func (g *nuguGame) sendRound() {
	if g.WaitingForGuess == true {
		return
	}

	// delete last round message if there was one.
{'fraction_non_alphanumeric': 0.09880287310454908, 'fraction_numerical': 0.0035115722266560257, 'mean_word_length': 3.5871156661786237, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '392908', 'n_tokens_mistral': 2412, 'n_tokens_neox': 2208, 'n_words': 572}