* Играта XO с GUI с NetBeans
Публикувано на 11 януари 2016 в раздел УКИ.
В този урок се запознаваме с GridLayout и работим с що-годе елементарни алгоритми за обхождане на масив. Реализираме играта XO с графична среда.
Отначало създайте нов проект в NetBeans и изберете "GridLayout" за основната рамка. На самия layout задайте 3 реда и 3 колони в неговите properties:
Така направена, рамката ще има нещо като невидима таблица с три реда и три колони. Когато добавяте обекти в рамката, те ще се вмъкват един по един в клетките на тази таблица.
Добавете 9 jLabel обекта в различните клетки. Променете имената им съответно на l1, l2, ... l9. Текстът на всеки етикет да е с голям шрифт и да е точка ".":
В началото добавете следните два imports:
import javax.swing.JLabel; import javax.swing.JOptionPane;
JOptionPane ще ни е нужен когато извеждаме диалогов прозорец при победа на един от двамата играчи. JLabel ще ни трябва за временна променлива (ще видите къде по-надолу.)
След това добавете следните три статични променливи в класа:
private static boolean xTurn = true; private static char board[][] = new char[3][3]; private static boolean gameFinished = false;
Чрез първата ще указваме кой играч е на ход. Ако xTurn е true, значи X е на ход. Ако e false, значи O е на ход. Board е масив, в който ще записваме ходовете на играчите. Той е двумерен и има 3 реда и 3 колони - точно както е в дъската на играта XO. Този масив е с елементи от тип char, т.е. символи. В неговите клетки ще записваме символите "X" или "O", когато играчът направи ход. Променливата gameFinished ще ни казва кога играта е завършила. Ще я използваме, за да можем да прекратим правенето на ход след приключване на играта.
Сега се върнете на Design View и добавете 9 поредни "mouse clicked" събития за всеки един от вашите етикети. Кодът на всеки един от тях ще е еднотипен:
private void l1MouseClicked(java.awt.event.MouseEvent evt) {
JLabel lbl = (JLabel) evt.getComponent();
if(!XOGui.gameFinished) this.turn(0,0,lbl);
}
private void l2MouseClicked(java.awt.event.MouseEvent evt) {
JLabel lbl = (JLabel) evt.getComponent();
if(!XOGui.gameFinished) this.turn(0,1,lbl);
}
private void l3MouseClicked(java.awt.event.MouseEvent evt) {
JLabel lbl = (JLabel) evt.getComponent();
if(!XOGui.gameFinished) this.turn(0,2,lbl);
}
private void l4MouseClicked(java.awt.event.MouseEvent evt) {
JLabel lbl = (JLabel) evt.getComponent();
if(!XOGui.gameFinished) this.turn(1,0,lbl);
}
private void l5MouseClicked(java.awt.event.MouseEvent evt) {
JLabel lbl = (JLabel) evt.getComponent();
if(!XOGui.gameFinished) this.turn(1,1,lbl);
}
private void l6MouseClicked(java.awt.event.MouseEvent evt) {
JLabel lbl = (JLabel) evt.getComponent();
if(!XOGui.gameFinished) this.turn(1,2,lbl);
}
private void l7MouseClicked(java.awt.event.MouseEvent evt) {
JLabel lbl = (JLabel) evt.getComponent();
if(!XOGui.gameFinished) this.turn(2,0,lbl);
}
private void l8MouseClicked(java.awt.event.MouseEvent evt) {
JLabel lbl = (JLabel) evt.getComponent();
if(!XOGui.gameFinished) this.turn(2,1,lbl);
}
private void l9MouseClicked(java.awt.event.MouseEvent evt) {
JLabel lbl = (JLabel) evt.getComponent();
if(!XOGui.gameFinished) this.turn(2,2,lbl);
}
В първия ред ние намираме кой точно етикет е бил натиснат. На втория ред правим ход, но само ако играта все още не е приключила.
Остава да направим метод turn. Създайте го със следния код (поставили сме подробни коментари с обяснение):
private void turn(int row, int column, JLabel toSwitch) {
// Ако сме цъкнали с мишката на поле, което вече е заето, не правим нищо
if (!toSwitch.getText().equals(".")){
return;
}
// Проверяваме дали на ход е X или O и го записваме в char
char labelText = XOGui.xTurn ? 'X' : 'O';
// Променяме текста на етикета с този символ
toSwitch.setText("" + labelText);
// Променяме и стойността на символа в масива
XOGui.board[row][column] = labelText;
// Проверяваме дали текущия играч е в печеливша позиция
// За целта сумираме броя на неговите символи в текущия ред
// текущата колона, по главния диагонал и по обратния диагонал.
int columnSum = 0, rowSum = 0, diagSum = 0, reverseDiagSum = 0;
for (int i = 0; i < 3; i++) {
if (XOGui.board[row][i] == labelText) columnSum++;
if (XOGui.board[i][column] == labelText) rowSum++;
if (XOGui.board[i][i] == labelText) diagSum++;
if (XOGui.board[i][2 - i] == labelText) reverseDiagSum++;
}
// Ако някоя от тези суми е 3, имаме печеливша позиция
if (rowSum == 3 || columnSum == 3 || diagSum == 3 || reverseDiagSum == 3) {
JOptionPane.showMessageDialog(this, labelText + " WINS");
XOGui.gameFinished = true;
}
// Обръщаме стойността на променливата така, че другия играч да е на ход
XOGui.xTurn = !XOGui.xTurn;
}
Допълнителна задача 1. Преработете програмата така, че най-долу да има още един ред. В него най-вдясно да има бутон "Нова Игра", който изчиства полето. До него да се показва статистика за това колко пъти X е побеждавал и колко пъти O. Например ето така (забележете, че за последната клетка сме използвали "Box Layout" с ориентиране по вертикала):
Допълнителна задача 2. Добавете контроли за съхраняване на статистиката във файл и за зареждане на статистика от файл, както е показано на картинката:




Добави коментар