Bounties
No. 1 (awarded)
I'll throw in 50 rep for the first valid answer
No. 2 (awarded)
I'll throw in another 100 rep for the shortest valid answer.
No. 3 (open for submissions)
I'll throw in 200 rep for the first one with a significant shorter valid answer. Significant being at most 45% of currently shortest answer (564 bytes x 0.45 = max 254 bytes).
The Game
You remember the classic game "Nine Men's Morris" or simply "Mill"? There's a variation called Three Men's Morris which is a bit like a mutable tic-tac-toe.
Rules
This is the blank board of the game:
a b c
1 [ ]–[ ]–[ ]
| \ | / |
2 [ ]–[ ]–[ ]
| / | \ |
3 [ ]–[ ]–[ ]
[ ]
is a field and |–/\
represent routes between those fields.
The game is played by two players 1
and 2
who each place 3 tokens on the board. This actually happened already and we are in the game. The game is won if one player can form a mill
which is a vertical or horizontal row of the player's 3 tokens.
Tokens can be moved on the board along the connecting lines, according to this rule:
To any adjacent empty position (i.e. from an edge position to the center, or from the center to an edge position, or from an edge position to an adjacent edge position
A player must make a move unless there's no adjacent empty position, in which case the move is skipped.
The Challenge
You're player 1
and your move is next. Write a program or a function, that determines whether:
- you can force a win with 2 or less moves (definite win)
- you can win with 2 or less moves, if your opponent makes a mistake (possible win)
- you cannot win with 2 or less moves, because you'll need more moves or because forced moves lead your opponent to win (impossible to win)
Requirements
- Even though you definitely win when you bore your opponent to death, your program must finish in finite time.
- You can write a program or a function.
Input
The players are represented by 1
and 2
. 0
defines a free field. You can take input as a matrix or an array.
Definite
A B C D
2 1 0 | 2 1 0 | 1 0 1 | 1 2 2
2 1 2 | 0 1 0 | 1 0 2 | 2 1 O
0 0 1 | 2 2 1 | 0 2 2 | O O 1
A: [2,1,0,2,1,2,0,0,1]
B: [2,1,0,0,1,0,2,2,1]
C: [1,0,1,1,0,2,0,2,2]
D: [1,2,2,2,1,0,0,0,1]
Possible
A B C
1 0 1 | 1 0 1 | 1 2 2
1 2 2 | 1 2 0 | 0 0 1
2 0 0 | 2 0 2 | 2 1 0
A: [1,0,1,1,2,2,2,0,0]
B: [1,0,1,1,2,0,2,0,2]
C: [1,2,2,0,0,1,2,1,0]
Impossible
A B
1 0 0 | 1 2 0
1 2 2 | 2 1 0
2 0 1 | 1 2 0
A: [1,0,0,1,2,2,2,0,1]
B: [1,2,0,2,1,0,1,2,0]
Output
Your program should output/return a smiley:
- Definite win:
:)
- Possible win:
:|
- Impossible to win:
:(
Examples
Definite win in two moves:
[2][1][ ] 1. [2][1][ ]
[2][1][2] -> [2][1][2]
[ ][ ][1] [ ][1][ ]
[2][1][ ] 1. [2][1][ ] [ ][1][ ] 2. [ ][ ][1]
[ ][1][ ] -> [ ][ ][1] -> [2][ ][1] -> [2][ ][1]
[2][2][1] [2][2][1] [2][2][1] [2][2][1]
[1][ ][1] 1. [ ][1][1] [ ][1][1] 2. [1][1][1]
[1][ ][2] -> [1][ ][2] -> [1][ ][2] -> [ ][ ][2]
[ ][2][2] [ ][2][2] [2][ ][2] [2][ ][2]
Possible win in two moves:
[1][ ][1] 1. [ ][1][1] [ ][1][1] 2. [1][1][1]
[1][2][ ] -> [1][2][ ] -> [1][2][2] -> [ ][2][2]
[2][ ][2] [2][ ][2] [2][ ][ ] [2][ ][ ]
[1][ ][1] 1. [ ][1][1] [ ][1][1] 2. [1][1][1]
[1][2][ ] -> [1][2][ ] -> [1][2][2] -> [ ][2][2]
[2][ ][2] [2][ ][2] [2][ ][ ] [2][ ][ ]
[1][2][2] 1. [ ][2][2] [2][ ][2] 2. [1][2][2]
[ ][ ][1] -> [1][ ][1] -> [1][ ][1] -> [1][1][1]
[2][1][ ] [2][1][ ] [2][1][ ] [2][ ][ ]
Impossible to win in two moves:
[1][ ][ ]
[1][2][2]
[2][ ][1]
Bonus
In case a definite win is possible and your program outputs the moves of one way to success as well like a1:a2
(1 move) or a1:a2,a3:b2
(2 moves), you can withdraw 30% of your byte count.
This is code golf – so shortest answer in bytes wins. Standard loopholes are disallowed.
Thanks to Peter Taylor who fixed some flaws and improved wording in the Sandbox.
[1,0,0,2,1,0,2,2,1]
, player 2 cannot move - is this a win for player 1? \$\endgroup\$