Existe uma maneira melhor de criar um jogo de galos e cruzes em LaTeX? Atualmente tenho o seguinte código:
\documentclass{beamer}
\mode<presentation>
\usepackage{amssymb}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amsthm}
\usepackage{array}
\usepackage{graphicx}
\begin{document}
\begin{frame}
\frametitle{A game of noughts and crosses}
Here is a game of noughts and crosses. On the left we have the game, and on the right the commentary.\\
\begin{columns}
\begin{column}{0.1\textwidth}
\vspace{1.75cm}
\begin{tabular}{c|c|c}
& & \\ \hline
& & \\ \hline
& &
\end{tabular}
\end{column} \pause
\begin{column}{0.70\textwidth}
\begin{itemize}
\item crosses goes first, makes optimal move. A good player will never lose from this start.
\end{itemize}
\end{column}
\end{columns}
\end{frame}
\end{document}
Isso divide o slide em dois, onde tenho o jogo de um lado e os comentários do outro. Quero poder jogar adicionando Os e Xs na grade, slide por slide, enquanto adiciono comentários simultaneamente. Claramente, o primeiro movimento é:
\begin{tabular}{c|c|c}
& & \\ \hline
& X & \\ \hline
& &
\end{tabular}
Só estou me perguntando se existe uma maneira melhor de fazer isso? Como faço para que o jogo preencha slide por slide (ou seja, X é reproduzido no slide 1, O é reproduzido no slide 2, adiciona comentários, X é reproduzido no slide 3, etc.).
Responder1
Quando houver muito código repetido (para jogos diferentes, neste caso), escrevo uma macro para simplificar meu arquivo latex - e para facilitar a alteração das coisas posteriormente, se necessário.
(EU)O primeiro pensamento que me veio à mente foi escrever uma macro que tome como “entrada”:
- uma lista separada por vírgulas das posições dos X
- uma lista separada por vírgulas das posições dos O's
- o comentário
As posições X e O eu codificaria como 1,2,...,9 lendo da esquerda para a direita e de cima para baixo na grade. Por exemplo, \NoughtsCrosses{5,6}{9}{Third move}
produziria
(II)Uma segunda maneira de fazer isso é assumir que os movimentos se alternam como X,O,X,... e apenas fornecer uma lista de movimentos separados por vírgula junto com o comentário. Por exemplo, \NoughtsCrossesII{5,9,6,4}{Fourth move}
produziria
Como o cfr diz nos comentários à pergunta, você provavelmente deseja colocar esses comandos dentro de algo como \only<5>{\NoughtsCrossesII{5,9,6,4}{Fourth move}}
para revelar um movimento de cada vez. Eu faço isso no MWE abaixo.
(III)Levando em conta a última observação, e indo um pouco OTT, uma macro mais inteligente simplesmente pegaria uma lista dos movimentos e comentários e então construiria todos os slides do jogo no quadro. Todas as macros até agora usam tikz e o \foreach
comando tikz permite múltiplas variáveis de loop separadas por uma barra, então a maneira mais fácil de implementar isso é usar a seguinte sintaxe:
\NoughtsCrossesGame{%
5/First move,
9/Second move,
6/Third move,
4/Fouth move
}
A saída é a "mesma" acima, exceto que o "jogo" aparece em 4 slides. A macro \NoughtsCrossesGame
usa um argumento opcional, que se comporta de maneira semelhante ao argumento opcional do \pause
comando. Ou seja, funciona como um “offset” controlando quando os movimentos do jogo começam a aparecer nos slides de um determinado quadro.
Aqui está o código que fornece as definições das três macros acima, completadas para um MWE para mostrar como usá-las:
\documentclass{beamer}
\usepackage{tikz}
% Helper macro for placing a node at "position" 1,2,...,9 into the grid
% \PlaceMarker[optional node styling]<position><X or O>
\usepackage{xparse}
\NewDocumentCommand\PlaceMarker{ O{}mm }{%
\ifnum#2>0
\def\markercol{#1}
\def\PlaceMakerNumber{#2}
\else
\def\markercol{red}
\def\PlaceMakerNumber{\numexpr-#2}
\fi
\ifcase\PlaceMakerNumber%
\or\node[\markercol] at (1,3) {#3}; % 1 = (3,1)
\or\node[\markercol] at (2,3) {#3}; % 2 = (3,2)
\or\node[\markercol] at (3,3) {#3}; % 3 = (3,3)
\or\node[\markercol] at (1,2) {#3}; % 4 = (2,1)
\or\node[\markercol] at (2,2) {#3}; % 5 = (2,2)
\or\node[\markercol] at (3,2) {#3}; % 6 = (2,3)
\or\node[\markercol] at (1,1) {#3}; % 7 = (1,1)
\or\node[\markercol] at (2,1) {#3}; % 8 = (1,2)
\or\node[\markercol] at (3,1) {#3}; % 9 = (1,3)
\fi
}
% Creates a noughts and cross game with commentary
%\NoughtsCrosses{x-positions}{y-positions}{Commentary}
\newcommand\NoughtsCrosses[3]{%
\begin{tikzpicture}
\foreach \x in {1.5,2.5} {
\draw[ultra thick](\x,0.5)--+(0,3);
\draw[ultra thick](0.5,\x)--+(3,0);
}
\foreach \x in {#1} {\PlaceMarker{\x}{X}}
\foreach \y in {#2} {\PlaceMarker{\y}{O}}
\node[text width=40mm,text ragged, anchor=west] at (5,3) {#3};
\end{tikzpicture}
}
% Creates a noughts and cross game with commentary
%\NoughtsCrossesII{move positions}{Commentary}
% Moves alternate as X,O,...
\newcommand\NoughtsCrossesII[2]{%
\begin{tikzpicture}
\foreach \x in {1.5,2.5} {
\draw[ultra thick](\x,0.5)--+(0,3);
\draw[ultra thick](0.5,\x)--+(3,0);
}
\foreach \move [count=\m] in {#1} {
\ifodd\m \PlaceMarker{\move}{X}
\else\PlaceMarker{\move}{O}
\fi
}
\node[text width=40mm,text ragged, anchor=west] at (5,3) {#2};% add comment
\end{tikzpicture}
}
% Creates a noughts and cross game with commentary
%\NoughtsCrossesII{move positions}{Commentary}
% Moves alternate as X,O,...
\makeatletter
\newcommand\NoughtsCrossesGame[2][0]{%
\begin{tikzpicture}
\foreach \x in {1.5,2.5} {
\draw[ultra thick](\x,0.5)--+(0,3);
\draw[ultra thick](0.5,\x)--+(3,0);
}
% count length of game
\foreach \move/\com [count=\lmove] in {#2} {}
\def\endgame{\the\numexpr\lmove+#1\relax}
\def\Endgame{\the\numexpr\endgame+1\relax}
\foreach \move/\com [count=\m,
evaluate=\m as \mm using int(\m+#1),
evaluate=\move as \mov using int(abs(-\move))] in {#2} {
\ifodd\m\def\Marker{X}
\else\def\Marker{O}
\fi
\def\mmm{\the\numexpr\mm+1\relax}
\only<\mm>{\PlaceMarker[blue]{\mov}{\Marker}}
\ifnum\move<0
\only<\mmm-\endgame>{\PlaceMarker{\mov}{\Marker}}
\only<\Endgame->{\PlaceMarker[blue]{\mov}{\Marker}}
\else
\only<\mmm->{\PlaceMarker{\mov}{\Marker}}
\fi
\only<\mm>{
\node[text width=40mm,text ragged, anchor=west] at (5,3){\com};
}
}
\end{tikzpicture}
}
\makeatother
\begin{document}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}{A game of noughts and crosses}
Here is a game of noughts and crosses. On the left we have the
game, and on the right the commentary.
\medskip
\only<2>{\NoughtsCrosses{5}{}{First move}}
\only<3>{\NoughtsCrosses{5}{9}{Second move}}
\only<4>{\NoughtsCrosses{5,6}{9}{Third move}}
\only<5>{\NoughtsCrossesII{5,9,6,4}{Fourth move}}
\end{frame}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{frame}{Another game of noughts and crosses}
Here is a game of noughts and crosses. On the left we have the
game, and on the right the commentary.
\pause Here is a clever game
\medskip
\NoughtsCrossesGame[1]{% offset start of game because of \pause above
-5/First move,
6/Middle square,
7/Forcing,
3/Forced block,
-9/Forced block leading to a pincer!,
8/Forced defence!,
-1/Wins!
}
\end{frame}
\end{document}
Alguns comentários:
- Todas as macros usamtikzdesenhar os jogos, pois isso dá melhor controle sobre a colocação dos marcadores X/O e no desenho da grade
- A
\PlaceMarker
macro é uma "função auxiliar" para colocar um marcador na posição especificada. Isso é usado\ifcase
para traduzir os índices de posição1,2,...,9
em(x,y)
coordenadas. - As macros são usadas
\foreach
para percorrer a lista separada por vírgulas de posições de marcadores. A segunda macro utiliza, além disso,\ifodd
para determinar se deve colocar um X ou um O. - O "comentário" é colocado dentro de um nó tikz como um texto irregular à esquerda com largura de 40 mm. Pode ser necessário ajustar o posicionamento das coordenadas (x,y) e a largura do texto.
- Conforme solicitado nos comentários, melhorei as macros para permitir fácil destaque de alguns dos movimentos. Fornecer um índice de "posição negativa" agora colore o
X
ou correspondenteO
. Por exemplo,\NoughtsCrosses{-5,-6}{9}{Third move}
tornará os doisX
vermelhos. - O mais divertido é que a
\NoughtsCrossesGame
macro agora colore cada movimento e depois coloca a sequência de "vitórias" final em azul no final do jogo - a sequência de vitórias deve novamente ser destacada usando índices de posição negativos. Em ambos os casos a coloração é feita por meio de um aprimoramento de\PlaceMarker
, embora a coloração automática de\NoughtsCrosses
seja mais complexa.
Para completar, aqui está uma versão animada do último slide produzido pelo \NoughtsCrossesGame
exemplo:
Exceto pelo quadro feito pelo beamer, esta coleção de slides é essencialmente a saída do comando:
\NoughtsCrossesGame[1]{% offset start of game because of \pause above
-5/First move,
6/Middle square,
7/Forcing,
3/Forced block,
-9/Forced block leading to a pincer!,
8/Forced defence!,
-1/Wins!
}