我想知道如何找到一個單元格通過所有具有相同值的單元格返回到起始單元格的路徑。 通過值在這裏,我的意思是要麼Token.CERCLE_ROUGE or Token.CERCLE_BLEU
二維數組尋路算法
考慮cell(4,5) == Token.CERCLE_BLEU
,有鄰居:3,4 - 4,4 - 5,4 - 3,5 - 5,5 - 3,6 - 4,6 - 5,6
個個== Token.CERCLE_ROUGE
現在我們有cell(3,4)
爲出發點:一是如何能找到一個路徑穿過(4,4), (5,4), (3,5), (5,5), (3,6), (4,6), (5,6)
再回到(3,4)
。在這裏,我們可以繪製一個從細胞到細胞的線段,因此cell(4,5)
將位於中心。 (見下圖)
這裏的想法是「捕捉」對手的標記,這就是玩家獲得積分的方式。
如果需要的話,我會用任何信息更新。
更新:
我發現了一個尋路工具,我認爲可以解決這個問題,但我不知道如何實現它:https://gist.github.com/benruijl/3385624
下面是我的代碼:
這個枚舉類代表小區狀態:
public enum Token {
VIDE, CERCLE_BLEU, CERCLE_ROUGE
}
我用下面的代碼來檢查電池的鄰居:
public void neighbours(int row, int col) {
for (int colNum = col - 1 ; colNum <= (col + 1) ; colNum +=1 ) {
for (int rowNum = row - 1 ; rowNum <= (row + 1) ; rowNum +=1 ) {
if(!((colNum == col) && (rowNum == row))) {
if(withinGrid (rowNum, colNum)) {
System.out.println("Neighbor of "+ row + " " + col + " is " + rowNum +" " + colNum +
" Contains "+ board[rowNum][colNum]);
}
}
}
}
}
private boolean withinGrid(int colNum, int rowNum) {
if((colNum < 0) || (rowNum <0)) {
return false;
}
if((colNum >= COLS) || (rowNum >= ROWS)) {
return false;
}
return true;
}
我的整個代碼如下。我還沒有能夠適應MVC,我所做的嘗試似乎不工作到目前爲止。
import javax.swing.JFrame;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
public final class Pha extends JFrame {
public static int ROWS = 15;
public static int COLS = ROWS;
public static int cellSize = 15;
public static int canvasWidth = cellSize * COLS + (ROWS *4) ;
public static int canvasHeight = cellSize * ROWS ;
public static int gridWidth = 1;
public static int halfGridWidth = gridWidth/2;
public static int cellPadding = cellSize/5;
public static int symbolSize = cellSize - cellPadding * 2;
public static int symbolStrokeWidth = 3;
public enum GameState{
JOUE, NUL, CERCLE_ROUGE_GAGNE, CERCLE_BLEU_GAGNE
}
private GameState actualState;
public enum Token{
VIDE, CERCLE_ROUGE, CERCLE_BLEU
}
private Token actualPlayer;
private Token[][] board;
private final DrawCanvas canvas;
private JLabel statusBar;
public Pha(){
canvas = new DrawCanvas();
canvas.setPreferredSize(new Dimension(canvasWidth, canvasHeight));
canvas.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
int x = e.getX();
int y = e.getY();
int selectedRow = y/cellSize;
int selectedCol;
selectedCol = x/cellSize;
if(actualState == GameState.JOUE){
if(selectedRow >= 0 && selectedRow < ROWS && selectedCol >= 0
&& selectedCol < COLS &&
board[selectedRow][selectedCol] == Token.VIDE){
board[selectedRow][selectedCol] = actualPlayer;
updateGame(actualPlayer, selectedRow, selectedCol);
actualPlayer = (actualPlayer == Token.CERCLE_BLEU)? Token.CERCLE_ROUGE : Token.CERCLE_BLEU;
neighbours(selectedRow, selectedCol);
}
} else {
initGame();
}
repaint();
}
});
statusBar = new JLabel(" ");
statusBar.setFont(new Font(Font.DIALOG_INPUT, Font.ITALIC, 15));
statusBar.setBorder(BorderFactory.createEmptyBorder(2, 5, 4, 5));
Container cp = getContentPane();
cp.setLayout(new BorderLayout());
cp.add(canvas, BorderLayout.EAST);
cp.add(statusBar, BorderLayout.NORTH);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setTitle("Pha par esQmo");
setVisible(true);
board = new Token[ROWS][COLS];
initGame();
}
public void initGame(){
for(int ligne = 0; ligne < ROWS; ++ligne){
for(int colonne = 0; colonne < COLS; ++colonne){
board[ligne][colonne] = Token.VIDE;
}
}
actualState = GameState.JOUE;
actualPlayer = Token.CERCLE_ROUGE;
}
public void updateGame(Token theSeed, int ligneSelectionnee, int colonneSelectionnee) {
if (aGagne(theSeed, ligneSelectionnee, colonneSelectionnee)) {
actualState= (theSeed == Token.CERCLE_ROUGE) ? GameState.CERCLE_ROUGE_GAGNE : GameState.CERCLE_BLEU_GAGNE;
} else if (estNul()) {
actualState = GameState.CERCLE_BLEU_GAGNE;
}
}
public boolean estNul() {
/*for (int row = 0; row < ROWS; ++row) {
for (int col = 0; col < COLS; ++col) {
if (board[row][col] == Token.VIDE) {
return false;
}
}
}*/
return false;
}
public boolean aGagne(Token token, int ligneSelectionnee, int colonneSelectionnee) {
return false;
}
public void neighbours(int row, int col) {
for (int colNum = col - 1 ; colNum <= (col + 1) ; colNum +=1 ) {
for (int rowNum = row - 1 ; rowNum <= (row + 1) ; rowNum +=1 ) {
if(!((colNum == col) && (rowNum == row))) {
if(withinGrid (rowNum, colNum)) {
System.out.println("Neighbor of "+ row + " " + col + " is " + rowNum +" " + colNum);
}
}
}
}
}
private boolean withinGrid(int colNum, int rowNum) {
if((colNum < 0) || (rowNum <0)) {
return false;
}
if((colNum >= COLS) || (rowNum >= ROWS)) {
return false;
}
return true;
}
class DrawCanvas extends JPanel{
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
setBackground(Color.WHITE);
g.setColor(Color.BLACK);
for(int ligne = 1; ligne < ROWS; ++ligne){
g.fillRoundRect(0, cellSize * ligne - halfGridWidth, canvasWidth - 1,
gridWidth, gridWidth, gridWidth);
}
for(int colonne = 1; colonne < COLS; ++colonne){
g.fillRoundRect(cellSize * colonne - halfGridWidth, 0
, gridWidth, canvasHeight - 1,
gridWidth, gridWidth);
}
Graphics2D g2d = (Graphics2D)g;
g2d.setStroke(new BasicStroke(symbolStrokeWidth,
BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
for(int ligne = 0; ligne < ROWS; ++ligne){
for(int colonne = 0; colonne < COLS; ++colonne){
int x1 = colonne * cellSize + cellPadding;
int y1 = ligne * cellSize + cellPadding;
if(board[ligne][colonne] == Token.CERCLE_ROUGE){
g2d.setColor(Color.RED);
g2d.drawOval(x1, y1, symbolSize, symbolSize);
g2d.fillOval(x1, y1, symbolSize, symbolSize);
} else
if(board[ligne][colonne] == Token.CERCLE_BLEU){
int x2 = colonne * cellSize + cellPadding;
g2d.setColor(Color.BLUE);
g2d.drawOval(x1, y1, symbolSize, symbolSize);
g2d.fillOval(x2, y1, symbolSize, symbolSize);
}
}
}
public static void main(String[] args){
SwingUtilities.invokeLater(() -> {
Pha pha = new Pha();
});
}
}
下面,MVC提出Hovercraft Full Of Eels作品,但並不如預期:
代表細胞狀態的枚舉類:
public enum Token {
VIDE, CERCLE_BLEU, CERCLE_ROUGE
}
控制:
import java.beans.IndexedPropertyChangeEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JFrame;
public class Control {
private Model model;
private View view;
public Control(Model model, View view) {
this.model = model;
this.view = view;
view.createGrid(model.getRows(), model.getCols());
view.getMainPanel().addPropertyChangeListener(new ViewListener());
model.addPropertyChangeListener(Model.TOKEN, new ModelListener());
}
private class ViewListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals(View.CELL_SELECTION)) {
int row = view.getSelectedRow();
int col = view.getSelectedCol();
Token token = model.getToken(row, col);
if (token == Token.VIDE) {
token = Token.CERCLE_BLEU;
} else if (token == Token.CERCLE_BLEU) {
token = Token.CERCLE_ROUGE;
} else {
token = Token.VIDE;
}
model.setToken(token, row, col);
}
}
}
private class ModelListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
IndexedPropertyChangeEvent iEvt = (IndexedPropertyChangeEvent)evt;
int index = iEvt.getIndex();
int row = index/Model.COLS;
int col = index % Model.COLS;
Token token = (Token) evt.getNewValue();
view.setCell(token, row, col);
}
}
public void start() {
JFrame frame = new JFrame("MVC");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(view.getMainPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
觀:
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.util.EnumMap;
import java.util.Map;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class View {
private static final int ICON_W = 12;
public static final String CELL_SELECTION = "cell selection";
private int rows;
private int cols;
private JPanel mainPanel = new JPanel();
private JLabel[][] grid;
private Map<Token, Icon> iconMap = new EnumMap<>(Token.class);
private int selectedRow;
private int selectedCol;
public View() {
iconMap.put(Token.VIDE, createIcon(new Color(0, 0, 0, 0)));
iconMap.put(Token.CERCLE_BLEU, createIcon(Color.BLUE));
iconMap.put(Token.CERCLE_ROUGE, createIcon(Color.RED));
}
private Icon createIcon(Color color) {
BufferedImage img = new BufferedImage(ICON_W, ICON_W, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = img.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(color);
g2.fillOval(1, 1, ICON_W - 2, ICON_W - 2);
g2.dispose();
return new ImageIcon(img);
}
public void createGrid(int rows, int cols) {
MyMouse myMouse = new MyMouse();
this.setRows(rows);
this.cols = cols;
mainPanel.setLayout(new GridLayout(rows, cols, 1, 1));
mainPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
mainPanel.setBackground(Color.BLACK);
grid = new JLabel[rows][cols];
for (int r = 0; r < grid.length; r++) {
for (int c = 0; c < grid[r].length; c++) {
grid[r][c] = new JLabel(iconMap.get(Token.VIDE));
grid[r][c].addMouseListener((MouseListener) myMouse); //cast
grid[r][c].setOpaque(true);
grid[r][c].setBackground(Color.WHITE);
mainPanel.add(grid[r][c]);
}
}
}
public JPanel getMainPanel() {
return mainPanel;
}
public int getSelectedRow() {
return selectedRow;
}
public int getSelectedCol() {
return selectedCol;
}
public void setCell(Token token, int row, int col) {
grid[row][col].setIcon(iconMap.get(token));
}
public int getRows() {
return rows;
}
public void setRows(int rows) {
this.rows = rows;
}
private class MyMouse extends MouseAdapter {
@Override
public void mousePressed(MouseEvent e) {
JLabel selection = (JLabel) e.getSource();
for (int r = 0; r < grid.length; r++) {
for (int c = 0; c < grid[r].length; c++) {
if (selection == grid[r][c]) {
selectedRow = r;
selectedCol = c;
int index = r * grid[r].length + c;
mainPanel.firePropertyChange(CELL_SELECTION, -1, index);
}
}
}
}
}
}
型號:
import java.beans.PropertyChangeListener;
import javax.swing.event.SwingPropertyChangeSupport;
public class Model {
public static final int ROWS = 75;
public static final int COLS = ROWS;
public static final String TOKEN = "token";
private Token[][] grid = new Token[ROWS][COLS];
private SwingPropertyChangeSupport pcSupport = new SwingPropertyChangeSupport(this);
public Model() {
for (int r = 0; r < grid.length; r++) {
for (int c = 0; c < grid[r].length; c++) {
grid[r][c] = Token.VIDE;
}
}
}
public Token getToken(int row, int col) {
return grid[row][col];
}
public void setToken(Token token, int row, int col) {
Token oldValue = grid[row][col];
Token newValue = token;
grid[row][col] = token;
int index = row * grid[row].length + col;
pcSupport.fireIndexedPropertyChange(TOKEN, index, oldValue, newValue);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
pcSupport.addPropertyChangeListener(listener);
}
public void addPropertyChangeListener(String name, PropertyChangeListener listener) {
pcSupport.addPropertyChangeListener(name, listener);
}
public int getRows() {
return ROWS;
}
public int getCols() {
return COLS;
}
}
主類:
import javax.swing.SwingUtilities;
public class Pha {
public static void main(String[] args) {
// run all on the Swing event thread
SwingUtilities.invokeLater(() -> {
Model model = new Model();
View view = new View();
Control control = new Control(model, view);
control.start();
});
}
}
從您的繪圖我明白,路徑應該只包含水平或垂直線。沒有對角線,對嗎? – c0der
對角線也。該圖只是一個例子 –
我在想像光標會從一個單元格移動到另一個單元格,檢查具有相同值的鄰居,然後畫出一條穿過該路徑中所有單元格的線...... –