我正在用java编写一个简单的TicTacToe游戏。 基本实现完成。 玩家与玩家正在完美地工作。
但是现在,当我实施AI时,我遇到了问题。 我已计算出计算机的移动,但我无法让计算机在JPanel上单击[带(x,y)坐标]的位置。
我已经看过机器人课程,但它没有点击所需的地方,似乎在窗外点击。
以下是代码,它在JPanel上绘制电路板:
private class Board extends JPanel{
/**
*
*/
private static final long serialVersionUID = 1L;
public Board(){
this.setSize(new Dimension(board_width, board_height));
this.setPreferredSize(new Dimension(board_width, board_height));
this.setBackground(new Color(0x84ACFF));
this.setOpaque(true);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
//g.setColor(new Color(0xf9d1af));
g.setColor(Color.white);
g.drawLine((board_width/3), 0, (board_width/3), board_height);
g.drawLine((board_width/3)*2, 0, (board_width/3)*2, board_height);
g.drawLine(0, (board_height/3), (board_width), (board_height/3));
g.drawLine(0, (board_height/3)*2, (board_width), (board_height/3)*2);
g.finalize();
}
}
这是我在JPanel中使用的mouseListener:
@Override
public void mousePressed(MouseEvent e) {
Graphics g = this.getGraphics();
int X = e.getX();
int Y = e.getY();
//JOptionPane.showMessageDialog(null, e.getXOnScreen()+":"+e.getYOnScreen());
int block_x = board_width/3;
int block_y = board_height/3;
X = X/block_x;
Y = Y/block_y;
//For array Assignment
Click_X = Y;
Click_Y = X;
//Keep copy of the originals
Orig_X = X;
Orig_Y = Y;
//------------------------------------------
// Assign to array & Draw
//------------------------------------------
if (computer){
if (start.equals("Computer")){
if (game_board[Click_X][Click_Y] != ' ') return;
moves++;
game_board[Click_X][Click_Y] = Cross;
drawCross(((X+1)*block_x)+25, ((Y+1)*block_y)+25, 50, 50, g);
dcsn = new Decision(game_board, moves);
}
else{
if (game_board[Click_X][Click_Y] != ' ') return;
moves++;
game_board[Click_X][Click_Y] = Nought;
drawNought(((X+1)*block_x), ((Y+1)*block_y), 50, 50, g);
dcsn = new Decision(game_board, moves);
}
}
else{
if (start.equals("Human")){
if (game_board[Click_X][Click_Y] != ' ') return;
moves++;
game_board[Click_X][Click_Y] = Cross;
drawCross(((X+1)*block_x)+25, ((Y+1)*block_y)+25, 50, 50, g);
dcsn = new Decision(game_board, moves);
}
else{
if (game_board[Click_X][Click_Y] != ' ') return;
moves++;
game_board[Click_X][Click_Y] = Nought;
drawNought(((X+1)*block_x), ((Y+1)*block_y), 50, 50, g);
dcsn = new Decision(game_board, moves);
}
}
switch (dcsn.gameOver()){
case "X":
JOptionPane.showMessageDialog(null,"X has won!");
break;
case "O":
JOptionPane.showMessageDialog(null,"O has won!");
break;
case "draw":
JOptionPane.showMessageDialog(null,"Draw!");
break;
case " ":
break;
}
switchTurn();
}
现在如何让计算机点击计算出的位置? 有什么想法吗?
以下是完整源代码的链接: Download Source
否则很难再现这种情况。
答案 0 :(得分:3)
我想像你在评论中建议的那样给你一个如何做的例子。 (“为什么不为每个单元格添加一个MouseListener ”,“你不需要机器人类”)当然你不需要做这样,但我觉得编码和编码更容易了解。现在,计算机只选择随机单元格,没有重启/输赢,我只是想向您展示这个概念。 在这种情况下我不会使用机器人类,程序应该无法控制光标;)
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.border.LineBorder;
public class TicTacToe {
Cell[][] cells = new Cell[3][3];
boolean humanTurn = true;
public TicTacToe() {
JFrame frame = new JFrame("T I C - T A C - T O E");
JPanel panel = new JPanel(new GridLayout(3, 3));
addCells(panel);
frame.add(panel);
frame.setSize(600, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
ActionListener actionListener = new ActionListener() {
Random r = new Random();
@Override
public void actionPerformed(ActionEvent e) {
if (!humanTurn) {
// Random cell
int x = r.nextInt(3);
int y = r.nextInt(3);
Cell cell = cells[x][y];
if (!cell.clicked) {
// Only the computer runs the gameloop, so false
cell.human = false;
cell.cross = false;
cell.repaint();
// Make sure the panel repaints before setting next
// booleans
EventQueue.invokeLater(new Runnable() {
public void run() {
humanTurn = true;
cell.clicked = true;
}
});
}
}
}
};
Timer gameloop = new Timer(10, actionListener);
gameloop.start();
}
private void addCells(JPanel panel) {
for (int y = 0; y < 3; y++) {
for (int x = 0; x < 3; x++) {
Cell cell = new Cell();
cell.setBorder(new LineBorder(Color.BLACK));
cells[x][y] = cell;
panel.add(cell);
}
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
new TicTacToe();
}
});
}
class Cell extends JPanel implements MouseListener {
boolean clicked = false;
boolean human = true;
boolean cross = false;
public Cell() {
addMouseListener(this);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D gg = (Graphics2D) g;
// Makes drawing smooth
gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// Drawing blue cross (player)
if (human && cross) {
gg.setColor(Color.BLUE);
gg.drawLine(20, 20, getWidth() - 20, getHeight() - 20);
gg.drawLine(getWidth() - 20, 20, 20, getHeight() - 20);
}
// Drawing red circle (computer)
else if (!human && !cross) {
gg.setColor(Color.RED);
gg.drawOval(10, 10, getWidth() - 20, getHeight() - 20);
}
}
@Override
public void mouseClicked(MouseEvent arg0) {
if (humanTurn && !clicked) {
// Only human can click on the panel, so true
human = true;
cross = true;
repaint();
// Make sure the panel repaints before setting next booleans
EventQueue.invokeLater(new Runnable() {
public void run() {
humanTurn = false;
clicked = true;
}
});
}
}
@Override
public void mouseEntered(MouseEvent arg0) {
}
@Override
public void mouseExited(MouseEvent arg0) {
}
@Override
public void mousePressed(MouseEvent arg0) {
}
@Override
public void mouseReleased(MouseEvent arg0) {
}
}
}