Ultimate Tic Tac Toe [Puzzle discussion]

could you please detail in the game-description how it is decided between the players in case of no player had three cases ranged ?
Thanks :slight_smile:

Yes, I’ll update the statement. When no players have 3 marks aligned, the winner is the player that won the most small boards (if the same number, that’s a draw).


This rule can be quite problematic. Ultimate Tic Tac Toe is an asymmetric game that is heavily in favor of the starting player. So much that one should be happy to get a draw as the second player.

The new rule makes the game even more one-sided. Usually getting a global three in a row involves sacrifices on the rest of the board, but this rule makes it so that the first player no longer has to do that! He can now focus on controlling small boards, which is easy, while preventing player 2 from making a line, which is also easy.
When the game is an easy win there is no way to differentiate bots by their strength and also because of how the rating system handles a “1-1” result, new submits can’t even climb the leaderboard!

I don’t mind some innovation, but if you change the default rules of Ultimate Tic Tac Toe then at least make sure the game becomes more even instead of more unbalanced.
I realise that the situation that I’m describing is not the case yet, but eventually it will be so it seems like a good idea to proactively address the issue.


Before making any modification to the rules, I’d like to hear the point of view on this matter from players that are in the top10.

My intent was to reduce the number of draws but I didn’t think that would increase the advantage given to the first player.

Currently, you always play twice: as first player and then as second player. The score is updated only once: win + win = WIN, win + draw = WIN, win + lose = DRAW, draw + draw = DRAW, lose + lose = LOSE, lose + draw = LOSE.

If the game is too unbalanced and player1 always wins, that will be a problem because at the end we’ll only have draws. Currently it doesn’t seem to be the case.

1 Like

I agree with Daporan. As an alternative, you could have :

  • No 3 aligned marks ? Draw, disregarding the small boards number. No incentive for the first player to play the deny-style Daporan described.
  • To reduce draws, account for the round difference in the swapped matches. i.e. in case of W/L give the win to the player who won his side the faster.

If there’s a consensus on that matter, I’ll change it, no problem. It’s a very easy change.

This would require major changes in our ranking system, I won’t have the time to work on that.

One more option:

a) first consider clear wins across the 2 matches
b) if equal, consider the grand total of small grids
c) if equal, consider the quickest win in rounds

Point c (cf @Neumann) should guarantee few draws, addressing the issue raised by @Daporan. The advantage of having b before is that is more obvious/dramatic (imo). Also this could add more depth to the game even if the 1st player advantage is high, since now you have to make tradeoffs between 3 different metrics, leading to different strategies, not just bruteforce and optimization :wink:

In general I think it’s also nice to depart from the standard uTTT when possible (more original, new challenges, less copy-paste, …).

If we remove the number of small boards without considering something else, there will be even more draws, no?

Agree… It is just a copy-paste from AI Games… Lets be original. Change some rule…

And, if it is to copy AI Games, please, copy the Time Bank feature… Or this will be more one game for C/C++ developers only…

I’m afraid that would also require massive changes in their platform :confused:

As far as I know uTTT was not invented by aigames, so it doesn’t really matter if it’s a copy or not, just like it doesn’t matter for Tron.

I think the biggest issue is, from my understanding, the ranking system throws away draws instead of feeding them to TrueSkill, which makes proper ranking difficult in draw-heavy games.

I also think it’s the only reason a draw-heavy game can be considered an issue at all, as it can naturally happen a lot with more ‘classic’ games like this or chess. I would much rather fix the ranking than try to add an arbitrary rule to an already well-established game (imagine changing chess to deal with draws), with little knowledge of the impact it will have on the game balance.

That being said, I don’t have any idea for better ‘rules’ at the moment, and my experience with the game is very limited (I started my bot barely a day ago), so I would trust Daporan’s experience with the game if he thinks the new rule isn’t good. Maybe we can also conduct further experiment with variants in a demo playground before bringing it to the official game?


Why are draws not fed to TrueSkill?

(and me was rejoicing of drawing DaFish sometimes :smiley: score update is lagging enough that it’s confusing and not always obvious what’s happening)

That’s something we configure for each game and for this game they are not thrown away.

1 Like

Good to know, thanks! Sorry for the misunderstanding.

This is great !

Out of curiosity, what are the games where draws are thrown away, and what was the reasoning behind it ?

I don’t remember which games do not take into consideration the draws but I can give you one example: Tron. In this game, the starting position is random and not symmetrical. Sometimes this leads to a huge advantage to one player (imagine if you’re in a corner of the map and the other can quickly block you). For this reason, it has been decided to throw away draws to only consider the games where there’s a clear winner.

1 Like

Hi, how to know when a new game started?
When I play first, if there is 81 valid actions or opponent’s row and col are -1 -1, I know its a new game. How to know if a new game started when I am the second player?

opponent’s row != -1 and it’s the first time you enter in your loop.

1 Like

I know that but it is every time I enter in the loop when I don’t play first! How to know a new game started when I play second? (We don’t have the current game state on each loop.)

Your program isn’t restarted on each game turn, you can store values in variables declared outside of the main loop. Basically, you can create a variable called “turn” outside from the loop, increment it inside the loop and test its value to know if it’s the first turn or not.