LaTeX でオッズゲームを構築するより良い方法はありますか? 現在、次のコードがあります:
\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}
これにより、スライドが 2 つに分割され、片側にゲーム、もう片側に解説が表示されます。スライドごとにグリッドに O と X を追加してゲームをプレイし、同時に解説を追加できるようにしたいと考えています。明らかに最初の動きは次のとおりです。
\begin{tabular}{c|c|c}
& & \\ \hline
& X & \\ \hline
& &
\end{tabular}
もっと良い方法はないでしょうか? ゲームをスライドごとに埋めていくにはどうしたらいいでしょうか (つまり、スライド 1 で X が再生され、スライド 2 で O が再生され、解説が追加され、スライド 3 で X が再生されるなど)。
答え1
繰り返しコードが多数ある場合 (この例では、さまざまなゲーム用)、LaTeX ファイルを簡素化し、必要に応じて後で変更しやすくするためのマクロを作成します。
(私)最初に思いついたのは、「入力」として受け取るマクロを書くことでした:
- Xの位置をカンマで区切ったリスト
- O の位置をカンマで区切ったリスト
- 解説
XとOの位置は、グリッドの左から右、上から下に1、2、...、9とコード化します。たとえば\NoughtsCrosses{5,6}{9}{Third move}
、
(II)2つ目の方法は、動きがX、O、X、...と交互に行われると仮定し、動きをカンマで区切ったリストを解説とともに与えることです。たとえば\NoughtsCrossesII{5,9,6,4}{Fourth move}
、
cfr が質問のコメントで述べているように、\only<5>{\NoughtsCrossesII{5,9,6,4}{Fourth move}}
一度に 1 つの動きを明らかにするには、これらのコマンドを のような内部で囲む必要があるでしょう。私は以下の MWE でこれを行います。
(III)最後のコメントを考慮し、少しやり過ぎかもしれませんが、よりスマートなマクロは、単に動きと解説のリストを取得し、フレーム内のゲームのすべてのスライドを構築することです。これまでのマクロはすべて tikz を使用しており、tikz\foreach
コマンドではスラッシュで区切られた複数のループ変数が許可されているため、これを実装する最も簡単な方法は次の構文を使用することです。
\NoughtsCrossesGame{%
5/First move,
9/Second move,
6/Third move,
4/Fouth move
}
出力は、ゲームが 4 つのスライドにわたって表示されることを除いて、上記と「同じ」です。マクロは\NoughtsCrossesGame
オプションの引数を取ります。これは、コマンドのオプションの引数と同様に動作します\pause
。つまり、ゲーム内の動きが特定のフレームのスライドにいつ表示され始めるかを制御する「オフセット」として機能します。
以下は、上記の 3 つのマクロの定義を示すコードです。MWE に完成されており、使用方法を示しています。
\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}
いくつかのコメント:
- すべてのマクロはティックズゲームを描画すると、X/Oマーカーの配置とグリッドの描画をより適切に制御できるようになります。
- この
\PlaceMarker
マクロは、指定された位置にマーカーを配置するための「ヘルパー関数」です。これは、\ifcase
位置インデックスを座標1,2,...,9
に変換するために使用されます(x,y)
。 - マクロは
\foreach
、マーカー位置のコンマ区切りリストをループするために使用します。さらに、2 番目のマクロは、\ifodd
X を配置するか O を配置するかを決定するために使用します。 - 「解説」は、幅 40 mm の不揃いな左テキストとして tikz ノード内に配置されます。(x,y) 座標の配置とテキストの幅を微調整する必要があるかもしれません。
- コメントでリクエストされたとおり、マクロを改良して、いくつかの動きが簡単にハイライト表示されるようにしました。「負の位置」インデックスを指定すると、対応する
X
または が色付けされるようになりましたO
。たとえば、\NoughtsCrosses{-5,-6}{9}{Third move}
は 2 つの を赤くしますX
。 - さらに面白いのは、
\NoughtsCrossesGame
マクロが各動きに色を付け、ゲームの最後に最終的な「勝利」の連勝を青で表示する点です。連勝は、負の位置インデックスを使用して再度強調表示する必要があります。どちらの場合も、色付けは の拡張機能によって行われますが\PlaceMarker
、 の自動色付けは\NoughtsCrosses
より複雑です。
完全を期すために、この例で作成された最後のスライドのアニメーション バージョンを以下に示します\NoughtsCrossesGame
。
beamer によって作成されたフレームを除いて、このスライドのコレクションは基本的に次のコマンドの出力です。
\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!
}