对Java基础算法与五子棋的小理解
·
一.计算最大公约数
- 首先,先要明白最大公约数是什么,就是可以同时整除a,b的数里面最大的
- 然后我们需要在数学上理通这个概念
首先设a,b两者的最大公约数是d,其中a比较大,余数是r,整数n,m
那么我们可以得出a=bd+r,r=a-bd,b=n d,a=m d,将后两式带入,m d=n d d+r,r=m d-n d d=d(m-n d),因为(m-n d)结果肯定是整数,所以r的因数是d,b的因数同样是d,所以a,b的公约数一定是b,r的公约数 - 随后,就可以重复此操作,由于我们设的是最大公约数,并且在上述操作过程中最大公约数不变,那么操作后的最后一个无法约分数即为所求
- 代码实现
while(b!=0){
int temp = b;
b = a % b;
a = temp;
}
二.斐波那契数列
- 递归的(数字太大会卡死)
if(k==1||k==2){
return 1;
}
return function(k-1)+function(k-2);
- 循环的
需要不断的一轮一轮的更新a,b,因为永远是a,b在相加
int a=1;
int b=1;
for(int i=3;i<=k;i++){
int c=a+b;
a=b;
b=c;
}
三.冒泡排序
- 首先其实就是两两对比,大的向前像泡泡一样向上浮动
- 他要进行n-1轮,并不是第一轮最大的就上1位了,而是最小的到最后一位了
for(int i=0;i<size-1;i++){
for(int j=0;j<size-1-i;j++){
if(arr[j]<arr[j+1]){
int temp =arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
- 当然,还可以选择Arrays.sort(arr),但他是从小到大,所以最后返回的时候他返回的是size-k
四.五子棋
1.判断落子后的输赢
要点:赢就是在一个方向上连5个,其大体思路就是遍历一个棋子的8个方向(有重复,只用写4个),找到同值的棋子就将找到的这个方向记录并延申.比较有意思的是方向的存储,首先在二维空间中想让描述关于坐标就必然要x,y也就是需要一个二维数组来存储x,y,通过加减就可以动起来,其实这个二维数组就可以说是存储了方向,由于加减,质押存储4个方向够了(五子棋中只有8个方向),注意x,y分别是行与列,
public static int isWin(int x, int y) {
int color = board[x][y];
int[][] dir = {{0, 1}, {1, 0}, {1, 1}, {1, -1}};
for (int[] d : dir) {
int count = 1;
for (int i = 1; ; i++) {
int nx = x + d[0] * i;
int ny = y + d[1] * i;
if (nx >= 0 && nx < 19 && ny >= 0 && ny < 19 && board[nx][ny] == color) {
count++;
} else {
break;
}
}
for (int i = 1; ; i++) {
int nx = x - d[0] * i;
int ny = y - d[1] * i;
if (nx >= 0 && nx < 19 && ny >= 0 && ny < 19 && board[nx][ny] == color) {
count++;
} else {
break;
}
}
if (count >= 5) {
return color;
}
}
return 0;
}
2.在合法的情况下给棋子附颜色的值(是有2个0,失败0与空地0(棋子的))
还是先进行一次合法的判断,随后还需要检查棋子本身是否是空白,随后再根据步数来赋值,在有两个if是可以用三元运算符来一步到位
public static int playerMove(int x, int y) {
if (x < 0 || x >= 19 || y < 0 || y >= 19) {
return 0;
}
board[x][y] = flag % 2 == 0 ? 1 : 2;
return 1;
}
3.初始菜单
普通的调用,1就直接调用封装好的gameview
while (true) {
System.out.println("===== 五子棋 =====");
System.out.println("1. 开始游戏");
System.out.println("2. 设置");
System.out.println("3. 退出");
System.out.print("请选择:");
int choose = scan.nextInt();
if (choose == 1) {
gameView();
} else if (choose == 2) {
System.out.println("敬请期待");
} else if (choose == 3) {
System.out.println("退出");
System.exit(0);
}
}
4.打印棋盘
第一行数字直接打印,但要注意对齐,由于左上角是空的,所以要提前打印空格,同时%3d来保持两两数字间的空格
public static void gameView_ShowBoard() {
System.out.print(" ");
for (int i = 0; i < 19; i++) {
System.out.printf("%3d", i);
}
System.out.println();
for (int i = 0; i < 19; i++) {
System.out.printf("%3d", i);
for (int j = 0; j < 19; j++) {
if (board[i][j] == 0) {
System.out.print(" x");
} else if (board[i][j] == 1) {
System.out.print(" ●");
} else if (board[i][j] == 2) {
System.out.print(" o");
}
}
System.out.println();
System.out.println();
}
}
5.打印胜利界面,并且可以回到初始菜单(执行完会自动返回调用函数)(第一个scan处理垃圾,第二个让程序停下来)
还是通过步数来判断什么棋子后再订谁赢
System.out.println("==================");
if (flag % 2 == 0) {
System.out.println(" 黑棋胜利!");
} else {
System.out.println(" 白棋胜利!");
}
System.out.println("==================");
System.out.println("按回车返回主菜单");
scan.nextLine();
scan.nextLine();
6.将所有功能集合到一个函数,再通过初始菜单一键调用
首先还是初始化,然后死循环中首先打印棋盘,然后三元运算符来表示该黑出还是白出,得到坐标先给顶坐标的,然后步数增加,棋盘也会相应的更新,直到第8手后才需要判断输赢,哦,当落子失败的时候对返回的0也要有一个判断,判赢后首先打印棋盘后在打印胜利截图(符合上面的排版)
public static void gameView() {
init();
while (true) {
gameView_ShowBoard();
String now = flag % 2 == 0 ? "黑棋" : "白棋";
System.out.println("当前:" + now);
System.out.print("输入x y:");
int x = scan.nextInt();
int y = scan.nextInt();
int res = playerMove(x, y);
if (res == 0) {
System.out.println("落子失败!");
continue;
}
int win = isWin(x, y);
if (win != 0) {
gameView_ShowBoard();
winView();
break;
}
flag++;
}
}
更多推荐




所有评论(0)