這篇文章主要介紹了Java怎么實現(xiàn)簡單井字棋小游戲,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
創(chuàng)新互聯(lián)是專業(yè)的裕民網(wǎng)站建設公司,裕民接單;提供網(wǎng)站建設、成都做網(wǎng)站,網(wǎng)頁設計,網(wǎng)站設計,建網(wǎng)站,PHP網(wǎng)站建設等專業(yè)做網(wǎng)站服務;采用PHP框架,可快速的進行裕民網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團隊,希望更多企業(yè)前來合作!

Java第一次實驗,老師讓做一個井字棋,電腦隨機下棋。
然后就想能不能聰明一點,可以判斷出走哪一步棋;然后只能做到不會輸,還是不夠聰明,只能呆板地堵住用戶,smartRobot的第三個判斷邏輯找不到最佳位置,贏得概率比較小;而且我沒事干時,想玩玩這個小游戲找找成就感,但每次都會贏了機器人,所以刪刪改改了四五次,最后才成。
可以選擇誰先開始,但startGame里的代碼更加冗余了。看著就很亂,但沒想到好的辦法。
smartRobot里的代碼全部重寫了,比原來更聰明一點了:下在四個角的位置時,能優(yōu)先選擇最佳位置;然后沒有最佳位置時,再隨便找一空的(隨便找空四角位置使用for代替了,比原來更簡短)。
然后smartRobot的第一個和第三個判斷邏輯,也更聰明一點了。原來判斷機器人和判斷用戶的邏輯,是放在一個for循環(huán)里的,但無法找到最佳位置,現(xiàn)在分開了。
機器人先開始時,才能發(fā)揮出來新添加的機器人的“小聰明”;但機器人原來的能力發(fā)揮不回來,只有用戶先開始時才能發(fā)揮出原來的能力。所以各有利弊,無論誰先開始都能適應。如果機器人先開始,并且用戶第一步棋不是下在四角的位置,那么用戶就必輸了。其他的情況一般都是平局了。
想到一個因為可以選擇誰先開始而導致 startGame 代碼冗余的問題的解決方法,就是使用局部內(nèi)部類。內(nèi)部類能訪問到方法的局部對象。
主邏輯 startGame:
1. 用一個3X3的二維數(shù)組,存儲棋盤;
2. 用戶輸入1~9下棋;
3. 判斷是否合法,不合法則重新輸入;
4. 將1~9轉(zhuǎn)換成二維的坐標 x = (pos-1)/3, y = (pos-1)%3,再令二維數(shù)組相應位置為 'O';
5. 判斷用戶是否勝利,是則退出;再判斷是否平局,是則退出;
6. 機器人下棋(根據(jù)輸入等級,調(diào)用不同函數(shù));
7. 打印棋盤顯示出用戶和機器人下的棋子;
8. 判斷機器人是否勝利,是則退出;再判斷是否平局,是則退出;都不是返回第1步。
isSuccessful 判斷成功的邏輯:
判斷所有行、列、對角線是否有連成一條線的,用字符相加的和判斷即可
willBeSuccessful判斷是否將要成功:
這里判斷的是是否有行、列有兩個相同棋子和一個空白,用字符相加的和判斷。
calculate 計算行列對角線:
使用枚舉類,來判斷是計算行,還是計算列,還是計算左右對角線;計算行列時,傳入一個1~3的數(shù)字表示是哪一行那一列。
smartRobot 的第一個判斷邏輯:
如果棋子下在箭頭指向的那個位置,那么一步棋就可勝利。
機器人先判斷自己是否有這樣一個位置,有則下在哪個地方,勝利;
方法是嘗試填入所有空白地方,每填一次,判斷一次 isSuccessful;
如果沒有,再判斷對方是否有這樣一個位置,有則堵住這個地方。

smartRobot 的第三個判斷邏輯:
如果棋子下在箭頭指向的位置,那么再下一步必會勝利,因為下在了那個地方,第三列、第三行都是兩個棋子了,無論對方堵哪里,都會失敗。
也是機器人先判斷自己是否有這樣一個位置,有則下;
調(diào)用 willBeSuccessful 判斷是否有這樣的位置。
沒有則再判斷對方是否有這樣的位置,有則堵住。

smartRobot 的第零個和第二個判斷邏輯:
處理四個角和中心的位置,如果用戶下在了中心,那么機器人必須至少有兩個棋子下在四角位置才能保證不輸。
更改了無數(shù)次的代碼:
import java.util.Arrays;
import java.util.Scanner;
public class Experiment_1 {
public static void main(String[] args) {
ThreeChess game = new ThreeChess();
game.startGame();
}
}
class ThreeChess{
private char[][] chessBoard = new char[3][3];
private int size = 0; //已經(jīng)下的棋數(shù)
private final int CAPACITY = 9; //總共可下的棋數(shù)
ThreeChess(){
for(char[] line : chessBoard){ //初始化棋盤
Arrays.fill(line, ' ');
}
}
//【游戲開始】
public void startGame(){
System.out.println("┌───┬───┬───┐");
System.out.println("│ 1 │ 2 │ 3 │");
System.out.println("├───┼───┼───┤");
System.out.println("│ 4 │ 5 │ 6 │");
System.out.println("├───┼───┼───┤");
System.out.println("│ 7 │ 8 │ 9 │");
System.out.println("└───┴───┴───┘");
System.out.println("輸入 1 ~ 9 表示要下棋的位置");
System.out.println("O是你的棋子,*是電腦的棋子");
Scanner in = new Scanner(System.in);
System.out.print("選擇誰先開始:\n\t1.用戶\n\t2.機器人\nInput: ");
int whoFirst = in.nextInt();
System.out.print("選擇機器人智商:\n\t1. 999+\n\t2. 250\nInput: ");
int level = in.nextInt();
class Play{ //代碼重用
//方法返回-1表示退出
int robotPlay(){
if(level == 1)
smartRobot();
else
sillyRobot();
printChessBroad();
if(isSuccessful() == -1) {
System.out.println("機器人勝 (/ □ \\)");
return -1;
}else if (size == CAPACITY){
System.out.println("==游戲平局==");
return -1;
}
return 0;
}
int userPlay(){
int pos;
while(true){
System.out.print("下棋位置: ");
pos = in.nextInt();
if(pos < 1
|| pos > 9
|| chessBoard[(pos - 1) / 3][(pos - 1) % 3] != ' '){
System.out.println("輸入錯誤,重新輸入!");
continue;
} else {
chessBoard[(pos - 1)/3][(pos - 1) % 3] = 'O';
size++;
break;
}
}
if(isSuccessful() == 1){
printChessBroad();
System.out.println("恭喜,你勝了 ╰(*°▽°*)╯");
return -1;
} else if(size == CAPACITY){
printChessBroad();
System.out.println("==游戲平局==");
return -1;
}
return 0;
}
}
Play play = new Play();
if(whoFirst == 2){
while(true){
//1.機器人下棋
if(play.robotPlay() == -1)
return;
//2.用戶下棋
if(play.userPlay() == -1)
return;
}
} else {
while(true){
//1.用戶下棋
if(play.userPlay() == -1)
return;
//2.機器人下棋
if(play.robotPlay() == -1)
return;
}
}
}
//【機器人下棋】
private void sillyRobot(){ //笨機器人
int l, c;
while(true){
l = (int)(Math.random() * 3);
c = (int)(Math.random() * 3);
if(chessBoard[l][c] == ' '){
chessBoard[l][c] = '*';
break;
}
}
size++;
}
private int corner = 2;
private void smartRobot(){ //無法戰(zhàn)勝的機器人
if(chessBoard[1][1] == ' '){ //搶占中心位置
chessBoard[1][1] = '*';
size++;
return;
}
//1.判斷是否可以下一個棋子就勝利(不能放在一起同時判斷,否則有可能錯誤最佳位置)
for(int i = 0; i < 3; i++){
for(int j = 0; j < 3; j++){
if(chessBoard[i][j] == ' '){ //【1】如果這個位置沒有棋子,就嘗試下載這個地方,看看是否可以勝;
chessBoard[i][j] = '*';
if(isSuccessful() == -1){ //【1】如果勝的話,就下在這個地方了,返回即可;
size++;
return ;
}
else
chessBoard[i][j] = ' ';
}
}
}
for(int i = 0; i < 3; i++){
for(int j = 0; j < 3; j++){
//【2】邏輯同【1】
if(chessBoard[i][j] == ' '){
chessBoard[i][j] = 'O'; //【2】否則嘗試用戶下在這個位置
if(isSuccessful() == 1){ //【2】如果用戶下在這個位置會勝利,就占領它。
chessBoard[i][j] = '*';
size++;
return ;
} else
chessBoard[i][j] = ' ';
}
}
}
//2.如果用戶下在了中間的話,就趕緊占兩個四角的位置,才能保證不輸。優(yōu)先級要比第一個低。用戶沒下在中間也可搶占。
if(corner > 0){
corner--;
for(int i = 0; i < 3; i++){ //優(yōu)先找四邊中沒有用戶棋子的地方下
if(i == 1)
continue;
boolean NoBigO = true;
for(int j = 0; j < 3; j++){
if(chessBoard[i][j] == 'O')
NoBigO = false;
}
for(int j = 0; j < 3 && NoBigO; j++){
if(chessBoard[i][j] == ' '){
chessBoard[i][j] = '*';
size++;
return;
}
}
}
for(int i = 0; i < 3; i++){
for(int j = 0; j < 3; j++){
if(j == 1 || i == 1)
continue;
if(chessBoard[i][j] == ' '){
chessBoard[i][j] = '*';
size++;
return;
}
}
}
} //end if
//3.判斷是否可以下一個棋子,從而再下一步可以勝利(不能放在一起判斷)
for(int i = 0; i < 3; i++){
for(int j = 0; j < 3; j++){
if(chessBoard[i][j] == ' '){
chessBoard[i][j] = '*';
if(willBeSuccessful(-1)){
size++;
return;
} else
chessBoard[i][j] = ' ';
}
}
}
for(int i = 0; i < 3; i++){
for(int j = 0; j < 3; j++){
if(chessBoard[i][j] == ' '){
chessBoard[i][j] = 'O';
if (willBeSuccessful(1)) {
chessBoard[i][j] = '*';
size++;
return;
} else
chessBoard[i][j] = ' ';
}
}
}
sillyRobot();
}
//【打印棋盤】
private void printChessBroad(){
System.out.println("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); //模擬清屏
System.out.println("┌───┬───┬───┐");
System.out.println("│ " + chessBoard[0][0] + " │ " + chessBoard[0][1] + " │ " + chessBoard[0][2] + " │");
System.out.println("├───┼───┼───┤");
System.out.println("│ " + chessBoard[1][0] + " │ " + chessBoard[1][1] + " │ " + chessBoard[1][2] + " │");
System.out.println("├───┼───┼───┤");
System.out.println("│ " + chessBoard[2][0] + " │ " + chessBoard[2][1] + " │ " + chessBoard[2][2] + " │");
System.out.println("└───┴───┴───┘");
}
//【判斷成功邏輯】
private enum Choice{
LINE, //行
COLUMN, //列
RIGHT_DIAGONAL, //右對角線
LEFT_DIAGONAL; //左對角線
}
private int calculate(Choice choice, int i){ //計算行、列、對角線是否連成一條線
switch (choice){
case LINE:
return chessBoard[i][0] + chessBoard[i][1] + chessBoard[i][2];
case COLUMN:
return chessBoard[0][i] + chessBoard[1][i] + chessBoard[2][i];
case RIGHT_DIAGONAL:
return chessBoard[0][0] + chessBoard[1][1] + chessBoard[2][2];
case LEFT_DIAGONAL:
return chessBoard[0][2] + chessBoard[1][1] + chessBoard[2][0];
}
return 0;
}
private int isSuccessful(){
/*
返回-1系統(tǒng)勝;返回1用戶勝;返回0表示繼續(xù)下棋。
系統(tǒng)勝:126 == '*' + '*' + '*'
用戶勝:237 == 'O' + 'O' + 'O'
*/
for(int i = 0; i < 3; i++){
if(calculate(Choice.LINE, i) == 237 || calculate(Choice.COLUMN, i) == 237)
return 1;
if(calculate(Choice.LINE, i) == 126 || calculate(Choice.COLUMN, i) == 126)
return -1;
}
if(calculate(Choice.LEFT_DIAGONAL, 0) == 237 || calculate(Choice.RIGHT_DIAGONAL, 0) == 237)
return 1;
if(calculate(Choice.LEFT_DIAGONAL, 0) == 126 || calculate(Choice.RIGHT_DIAGONAL, 0) == 126)
return -1;
return 0; //繼續(xù)下棋
}
private boolean willBeSuccessful(int who){ //who:-1表示判斷機器人的,+1表示判斷用戶的。
//如果行、列、對角線有2個相同棋子的個數(shù),則將會勝,
//190 == 2 * 'O' + ' '
//116 == 2 * '*' + ' '
int n = 0;
int s = (who == 1) ? 190 : 116; //用戶or機器人要計算的值
for(int i = 0; i < 3; i++){
if(calculate(Choice.LINE, i) == s)
n++;
if(calculate(Choice.COLUMN, i) == s)
n++;
}
//因為中心一定會被占的,所以就不用判斷對角線了
return n > 1;
}
}感謝你能夠認真閱讀完這篇文章,希望小編分享的“Java怎么實現(xiàn)簡單井字棋小游戲”這篇文章對大家有幫助,同時也希望大家多多支持創(chuàng)新互聯(lián),關注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關知識等著你來學習!
文章題目:Java怎么實現(xiàn)簡單井字棋小游戲
文章URL:http://chinadenli.net/article6/gdgdog.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站建設、云服務器、網(wǎng)站導航、品牌網(wǎng)站設計、網(wǎng)站排名、企業(yè)建站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)