Отправьте свой самый короткий код счетчиком символов, чтобы проверить, победил ли игрок, и если так, который.
Предположите, что у Вас есть целочисленный массив в переменной b
(плата), которая содержит Тик плата Пальца ноги Tac и перемещения плееров где:
Так, учитывая массив b = [ 1, 2, 1, 0, 1, 2, 1, 0, 2 ]
представил бы плату
X|O|X
-+-+-
|X|O
-+-+-
X| |O
Для той ситуации Ваш код должен произвести 1
указать на плеер 1 победило. Если никто не победил, можно произвести 0
или false
.
Мое собственное (Ruby) решение скоро произойдет.
Править: Извините, забыл отмечать его как общественную Wiki. Можно предположить, что вход хорошо формируется и не должен быть проверенной ошибкой.
Обновление: отправьте свое решение в форме функции. Большинство людей уже сделало это, но некоторые не имеют, который не совершенно справедлив. Плата предоставляется Вашей функции как параметр. Результат должен быть возвращен функцией. Функция может иметь название Вашего выбора.
C #, 148 Я думаю.
int[] m={0,1,3,1,6,1,0,3,1,3,2,3,0,4,2,2};int i,s,w,r=0,o;for(i=0;i<16;i+=2){s=m[i];w=m[i+1];o=v[s];if((o==v[w+s])&&(o==v[s+(w*2)])){r=o;}}return r;
def s(b)(0..8).to_a+[0,3,6,1,4,7,2,5,8,0,4,8,2,4,6].each_slice(3){|m|if b.values_at(*m).uniq.length<2&&b[m[0]]!=0;return b[m[0]];end}return false;end
Это достаточно простое решение, я уверен, что смогу его еще немного сократить. Вот читаемая версия:
def someone_won(b)
helper = (0..8).to_a + [ 0, 3, 6, 1, 4, 7, 2, 5, 8, 0, 4, 8, 2, 4, 6]
helper.each_slice(3) { |m|
if b.values_at(*m).uniq.length < 2 && b[m[0]] != 0
return b[m[0]]
end
}
return false
end
После долгих трудов над моим первым кодом, я смог сократить функцию до 155 символов (будьте прокляты скобки массива!). С помощью некоторых математических трюков я смог обобщить проверку на три клетки для горизонталей, вертикалей и диагоналей. Кроме того, я самостоятельно обнаружил то, что, как я вижу, отметил Эрик Пи, о проверке эквивалентности триплетов с помощью побитовых and. Мой метод:
int i=-1,j,w=0;int[]a={0,0,2,0,9,3,3,1,3,1,1,1,1,3,2,4};while(++i<4)for(j=a[i];j<a[i+4];j+=a[i+8])if((g[j]&g[j+a[i+12]]&g[j+2*a[i+12]])>0)w=g[j];return w;
Также я создал класс для генерации всех допустимых досок для тестирования (это не так просто, как кажется). Для тех из вас, кто заинтересован в попытке улучшить 155 на Java, вот мой класс для тестирования:
public class TicTacToe
{
public static void main(String[] args)
{
int[][] boards = generateBoards();
for(int i = 0; i < boards.length; ++i)
{
int winner = getWinner(boards[i]);
System.out.println(winner + " " + boards[i][0] + " " + boards[i][1] + " " + boards[i][2]);
System.out.println( " " + boards[i][3] + " " + boards[i][4] + " " + boards[i][5]);
System.out.println( " " + boards[i][6] + " " + boards[i][7] + " " + boards[i][8]);
System.out.println();
}
}
public static int getWinner(int[] g)
{
int i=-1,j,w=0;int[]a={0,0,2,0,9,3,3,1,3,1,1,1,1,3,2,4};while(++i<4)for(j=a[i];j<a[i+4];j+=a[i+8])if((g[j]&g[j+a[i+12]]&g[j+2*a[i+12]])>0)w=g[j];return w;
}
public static boolean isValid(int[] board)
{
// O = 0 : X = 1
int counts[] = new int[2];
// Count the number of Xs and Os
for(int i = 0; i < 9; ++i)
if(board[i] > 0)
++counts[board[i] - 1];
// Make sure the counts make sense. If not return "no"
if(!(counts[1] == counts[0] || counts[1] == counts[0] + 1))
return false;
// Now we're going to total the number of horizontal/vertical wins
int wins[] = new int[2];
// Check rows
if(board[0] != 0 && board[0] == board[1] && board[1] == board[2]) ++wins[board[0] - 1];
if(board[3] != 0 && board[3] == board[4] && board[4] == board[5]) ++wins[board[3] - 1];
if(board[6] != 0 && board[6] == board[7] && board[7] == board[8]) ++wins[board[6] - 1];
// Check columns
if(board[0] != 0 && board[0] == board[3] && board[3] == board[6]) ++wins[board[0] - 1];
if(board[1] != 0 && board[1] == board[4] && board[4] == board[7]) ++wins[board[1] - 1];
if(board[2] != 0 && board[2] == board[5] && board[5] == board[8]) ++wins[board[2] - 1];
// Make sure the win counts make sense
if(wins[0] > 1 && wins[1] > 1)
return false;
// Hmmmm... I guess it's a valid board
return true;
}
public static int[][] generateBoards()
{
int boardSize = 9;
int permutationCount = (int)Math.pow(4, 9);
int[][] boards = new int[permutationCount][boardSize];
int actualIndex = 0;
for(int i = 0; i < permutationCount; ++i)
{
boolean isUnique = true;
for(int j = 0; j < boardSize; ++j)
{
int x = (i >>> j) & 3;
if(x == 3)
isUnique = false;
boards[actualIndex][j] = x;
}
if(isUnique && isValid(boards[actualIndex]))
++actualIndex;
}
return Arrays.copyOf(boards, actualIndex);
}
}
Неплохо, я полагаю, для простой java без каких-либо экзотических вызовов функций. Наслаждайтесь!
LinQ 236
Возможно, в C # можно было бы получить меньше без объявления функции;)
Function P(ByVal b())
Dim s() = "012.048.036.147.258.345.678".Split(".")
If (From x In s Where b(Val(x(0))) & b(Val(x(1))) & b(Val(x(2))) = "111").Any Then Return 1
If (From x In s Where b(Val(x(0))) & b(Val(x(1))) & b(Val(x(2))) = "222").Any Then Return 2
Return 0
End Function
Режим гольфа:
(defun x(b)(find-if-not 'null(mapcar(lambda(r)(let((v(mapcar(lambda(c)(elt b c))r)))(if(apply '= v)(car v))))'((0 1 2)(3 4 5)(6 7 8)(0 3 6)(1 4 7)(2 5 8)(0 4 8)(2 4 6)))))
Режим чтения:
(defun ttt-winner (board)
(find-if-not 'null
(mapcar (lambda (row)
(let ((vals (mapcar (lambda (cell) (elt board cell)) row)))
(if (apply '= vals) (car vals))))
'((0 1 2) (3 4 5) (6 7 8) (0 3 6) (1 4 7) (2 5 8) (0 4 8) (2 4 6)))))