* Играта 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. Добавете контроли за съхраняване на статистиката във файл и за зареждане на статистика от файл, както е показано на картинката:
Добави коментар