patternjavaMinor
Noughts and Crosses GUI game in Java - Part 1/2: AI
Viewed 0 times
partjavagameandguinoughtscrosses
Problem
(See also Noughts and Crosses GUI game in Java - Part 2/2: GUI)
I was working on a GUI game of Noughts and Crosses, and this is what I finally got:
Unfortunately, the entire source code for the program does not fit in a single, so I have to try to split them in logical parts: this post is about Model and a little bit of Controller in MVC-pattern.
AIThread.java:
```
package net.coderodde.game.crosses;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
/**
* This thread is responsible for running the AI.
*
* @author Rodion "rodde" Efremov
* @version 1.6 (Oct 7, 2015)
*/
class AIThread extends Thread {
private static final double LARGE = 1e10;
private final ConfigurationFrame configurationFrame;
private final GameFrame gameFrame;
private final JProgressBar progressBar;
private final TicTacToeGrid grid;
private final TicTacToePanel canvas;
private final MoveGenerator moveGenerator;
private final HeuristicFunction heuristicFunction;
private final int maximumDepth;
AIThread(ConfigurationFrame configurationFrame,
GameFrame gameFrame,
TicTacToeGrid grid,
TicTacToePanel canvas,
JProgressBar progressBar,
MoveGenerator moveGenerator,
HeuristicFunction heuristicFunction,
int maximumDepth) {
this.configurationFrame = configurationFrame;
this.gameFrame = gameFrame;
this.grid = grid;
this.canvas = canvas;
this.progressBar = progressBar;
this.moveGenerator = moveGenerator;
this.heuristicFunction = heuristicFunction;
this.maximumDepth = maximumDepth;
}
@Override
public void run() {
canvas.lock(); // Make sure that the user's clicks do not modify the
// grid.
I was working on a GUI game of Noughts and Crosses, and this is what I finally got:
Unfortunately, the entire source code for the program does not fit in a single, so I have to try to split them in logical parts: this post is about Model and a little bit of Controller in MVC-pattern.
AIThread.java:
```
package net.coderodde.game.crosses;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
/**
* This thread is responsible for running the AI.
*
* @author Rodion "rodde" Efremov
* @version 1.6 (Oct 7, 2015)
*/
class AIThread extends Thread {
private static final double LARGE = 1e10;
private final ConfigurationFrame configurationFrame;
private final GameFrame gameFrame;
private final JProgressBar progressBar;
private final TicTacToeGrid grid;
private final TicTacToePanel canvas;
private final MoveGenerator moveGenerator;
private final HeuristicFunction heuristicFunction;
private final int maximumDepth;
AIThread(ConfigurationFrame configurationFrame,
GameFrame gameFrame,
TicTacToeGrid grid,
TicTacToePanel canvas,
JProgressBar progressBar,
MoveGenerator moveGenerator,
HeuristicFunction heuristicFunction,
int maximumDepth) {
this.configurationFrame = configurationFrame;
this.gameFrame = gameFrame;
this.grid = grid;
this.canvas = canvas;
this.progressBar = progressBar;
this.moveGenerator = moveGenerator;
this.heuristicFunction = heuristicFunction;
this.maximumDepth = maximumDepth;
}
@Override
public void run() {
canvas.lock(); // Make sure that the user's clicks do not modify the
// grid.
Solution
Thread safety is pretty poor.
Instead of making threads I suggest you change the WorkerThreads into
Then you can submit it to a
This should be created and held by canvas to allow the executor and it threads to be reused as needed.
Instead of making threads I suggest you change the WorkerThreads into
Callable and make the call() do only a single workItemList and return the best move.Then you can submit it to a
ExecutorService's invokeAll() which will distribute the work over several cores automatically. (You can get a ExecutorService using Executors.newCachedThreadPool())This should be created and held by canvas to allow the executor and it threads to be reused as needed.
for (int i = 0; i wt.getBestValue()) {
bestValue = wt.getBestValue();
bestState = wt.getBestState();
}
}Code Snippets
for (int i = 0; i < cores; ++i) {
workItemLists.add(new WorkerCallable(workItemListCapacity,
moveGenerator,
heuristicFunction,
maximumDepth,
progressBar));
}
canvas.getExecutorService().invokeAll(workItemLists);
TicTacToeGrid bestState = workItemLists.get(0).getBestState();
double bestValue = workItemLists.get(0).getBestValue();
for (WorkerCallable wt : workItemLists) {
if (bestValue > wt.getBestValue()) {
bestValue = wt.getBestValue();
bestState = wt.getBestState();
}
}Context
StackExchange Code Review Q#106915, answer score: 4
Revisions (0)
No revisions yet.