问题描述
考虑一个具有 n 行
和 n 列
(此处为 75x75)的 2D 网格.鼠标单击时在每个单元格中绘制符号(标记).下面的代码用于在单元格内绘制网格线和符号:
Consider a 2D grid with n rows
and n columns
(here 75x75). The symbols (tokens) are drawn in each cell on mouse click. The code below is used to draw grid lines and symbols within cells:
class DrawCanvas extends JPanel{
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
setBackground(Color.WHITE);
//Lines
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);
}
//Symbols
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);
}
}
}
使用下面的代码,我可以找到给定单元格的所有邻居:
With the code below, I can find all neighbors of a given cell:
private void neighbours(int col, int row) {
//find all serouding cell by adding +/- 1 to col and row
for (int colNum = col - 1 ; colNum <= (col + 1) ; colNum +=1 ) {
for (int rowNum = row - 1 ; rowNum <= (row + 1) ; rowNum +=1 ) {
//if not the center cell
if(! ((colNum == col) && (rowNum == row))) {
//make sure it is within grid
if(withinGrid (colNum, rowNum)) {
System.out.println("Neighbor of "+ col+ " "+ row + " - " + colNum +" " + rowNum );
}
}
}
}
}
//define if cell represented by colNum, rowNum is inside grid
private boolean withinGrid(int colNum, int rowNum) {
if((colNum < 0) || (rowNum <0) ) {
return false; //false if row or col are negative
}
if((colNum >= COLS) || (rowNum >= ROWS)) {
return false; //false if row or col are > 75
}
return true;
}
考虑单元格内容:
public enum Token{
VIDE, CERCLE_BLEU, CERCLE_ROUGE
}
现在我想知道是否有办法确定单元格包含的内容:是否为空:Token.VIDE
、有 Token.CERCLE_BLEU
还是有 Token.CERCLE_ROUGE.
以及如何实现.
Now I want to know if there is a way to determinate what a cell contains: is it empty: Token.VIDE
, has Token.CERCLE_BLEU
or has Token.CERCLE_ROUGE.
And how I can achieve that.
更新:以下是我的代码:
UPDATE: Below is my code:
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 = 75;
public static int COLS = 75;
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){ //Invoqué via repaint()
super.paintComponent(g); //Pour remplir l'arriere plan
setBackground(Color.WHITE); //Defini la couleur de l'arriere plan
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);
}
}
}
if(actualState == GameState.JOUE){
if(actualPlayer == Token.CERCLE_ROUGE){
statusBar.setText("ROUGE, c'est votre tour");
statusBar.setForeground(Color.RED);
} else {
statusBar.setText("BLEU, c'est votre tour");
statusBar.setForeground(Color.BLUE);
statusBar.addMouseMotionListener(null);
}
} else
if(actualState == GameState.NUL){
statusBar.setForeground(Color.yellow);
statusBar.setText("Match nul! Cliquez pour rejouer");
} else
if(actualState == GameState.CERCLE_ROUGE_GAGNE){
statusBar.setText("Le jouer X a remporté la partie, cliquez pour rejouer");
statusBar.setForeground(Color.RED);
} else
if(actualState == GameState.CERCLE_BLEU_GAGNE){
statusBar.setForeground(Color.BLUE);
statusBar.setText("Le joueur O a remporté la partie, cliquez pour rejouer");
}
}
}
public static void main(String[] args){
SwingUtilities.invokeLater(() -> {
Pha pha = new Pha();
});
}
}
推荐答案
在 board
数组中存储每个单元格的 Token
.
要检索此信息,您可以更改
In board
array you store the Token
for each cell.
To retrieve this information you could change
System.out.println("Neighbor of "+ row + " " + col + " is " + rowNum +" " + colNum );
在neighbors()
中:
System.out.println("Neighbor of "+ row + " " + col + " is " + rowNum +" " + colNum +
" Contains "+ board[rowNum][colNum]);
单击中间单元格 (17,19):
Clicking the middle cell (17,19):
打印出来:
17 19 的邻居是 16 18 包含 CERCLE_ROUGE
17 19 的邻居是17 18 包含 CERCLE_BLEU
17 19 的邻居是 18 18 包含CERCLE_ROUGE
17 19 的邻居是 16 19 包含 CERCLE_BLEU
邻居17 19 是 18 19 包含 CERCLE_BLEU
17 19 的邻居是 16 20包含 CERCLE_ROUGE
17 19 的邻居是 17 20 包含 CERCLE_BLEU
17 19 的邻居是 18 20 包含 CERCLE_ROUGE
Neighbor of 17 19 is 16 18 Contains CERCLE_ROUGE
Neighbor of 17 19 is 17 18 Contains CERCLE_BLEU
Neighbor of 17 19 is 18 18 Contains CERCLE_ROUGE
Neighbor of 17 19 is 16 19 Contains CERCLE_BLEU
Neighbor of 17 19 is 18 19 Contains CERCLE_BLEU
Neighbor of 17 19 is 16 20 Contains CERCLE_ROUGE
Neighbor of 17 19 is 17 20 Contains CERCLE_BLEU
Neighbor of 17 19 is 18 20 Contains CERCLE_ROUGE
这篇关于如何根据二维数组上的特定位置获取网格单元的状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!