很sb的电脑五子棋:
import javaio;
import javautil;
public class Gobang {
// 定义一个二维数组来充当棋盘
private String[][] board;
// 定义棋盘的大小
private static int BOARD_SIZE = 15;
public void initBoard() {
// 初始化棋盘数组
board = new String[BOARD_SIZE][BOARD_SIZE];
// 把每个元素赋为"╋",用于在控制台画出棋盘
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
// windows是一行一行来打印的。坐标值为(行值, 列值)
board[i][j] = "╋";
}
}
}
// 在控制台输出棋盘的方法
public void printBoard() {
// 打印每个数组元素
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
// 打印数组元素后不换行
Systemoutprint(board[i][j]);
}
// 每打印完一行数组元素后输出一个换行符
Systemoutprint("\n");
}
}
// 该方法处理电脑下棋:随机生成2个整数,作为电脑下棋的坐标,赋给board数组。
private void compPlay() {
// 构造一个随机数生成器
Random rnd = new Random();
// Random类的nextInt(int n))方法:随机地生成并返回指定范围中的一个 int 值,
// 即:在此随机数生成器序列中 0(包括)和 n(不包括)之间均匀分布的一个int值。
int compXPos = rndnextInt(15);
int compYPos = rndnextInt(15);
// 保证电脑下的棋的坐标上不能已经有棋子(通过判断对应数组元素只能是"╋"来确定)
while (board[compXPos][compYPos]equals("╋") == false) {
compXPos = rndnextInt(15);
compYPos = rndnextInt(15);
}
Systemoutprintln(compXPos);
Systemoutprintln(compYPos);
// 把对应的数组元素赋为"○"。
board[compXPos][compYPos] = "○";
}
// 该方法用于判断胜负:进行四次循环扫描,判断横、竖、左斜、右斜是否有5个棋连在一起
private boolean judgeWin() {
// flag表示是否可以断定赢/输
boolean flag = false;
// joinEle:将每一个横/竖/左斜/右斜行中的元素连接起来得到的一个字符串
String joinEle;
// 进行横行扫描
for (int i = 0; i < BOARD_SIZE; i++) {
// 每扫描一行前,将joinEle清空
joinEle = "";
for (int j = 0; j < BOARD_SIZE; j++) {
joinEle += board[i][j];
}
// String类的contains方法:当且仅当该字符串包含指定的字符序列时,返回true。
if (joinElecontains("●●●●●")) {
Systemoutprintln("您赢啦!");
flag = true;
// 停止往下继续执行,提前返回flag。
// 如果执行了这个return,就直接返回该方法的调用处;
// 不会再执行后面的任何语句,包括最后那个return语句。
// (而break仅仅是完全跳出这个for循环,还会继续执行下面的for循环。)
return flag;
} else if (joinElecontains("○○○○○")) {
Systemoutprintln("您输啦!");
flag = true;
// 提前返回flag
return flag;
}
}
// 进行竖行扫描
for (int i = 0; i < BOARD_SIZE; i++) {
joinEle = "";
for (int j = 0; j < BOARD_SIZE; j++) {
// 竖行的元素是它们的列值相同
joinEle += board[j][i];
}
if (joinElecontains("●●●●●")) {
Systemoutprintln("您赢啦!");
flag = true;
return flag;
} else if (joinElecontains("○○○○○")) {
Systemoutprintln("您输啦!");
flag = true;
return flag;
}
}
// 进行左斜行扫描
for (int i = -(BOARD_SIZE - 2); i < BOARD_SIZE - 1; i++) {
joinEle = "";
for (int j = 0; j < BOARD_SIZE; j++) {
int line = i + j;
// 只截取坐标值没有越界的点
if (line >= 0 && line < 15) {
joinEle += board[j][line];
}
}
if (joinElecontains("●●●●●")) {
Systemoutprintln("您赢啦!");
flag = true;
return flag;
} else if (joinElecontains("○○○○○")) {
Systemoutprintln("您输啦!");
flag = true;
return flag;
}
}
// 进行右斜行扫描
for (int i = 1; i < 2 (BOARD_SIZE - 1); i++) {
joinEle = "";
for (int j = 0; j < BOARD_SIZE; j++) {
int line = i - j;
if (line >= 0 && line < 15) {
joinEle += board[j][line];
}
}
if (joinElecontains("●●●●●")) {
Systemoutprintln("您赢啦!");
flag = true;
return flag;
} else if (joinElecontains("○○○○○")) {
Systemoutprintln("您输啦!");
flag = true;
// 最后这个return可省略
}
}
// 确保该方法有返回值(如果上面条件都不满足时)
return flag;
}
public static void main(String[] args) throws Exception, IOException {
Gobang gb = new Gobang();
gbinitBoard();
gbprintBoard();
// BufferedReader类:带缓存的读取器————从字符输入流中读取文本,并缓存字符。可用于高效读取字符、数组和行。
// 最好用它来包装所有其 read() *** 作可能开销很高的 Reader(如 FileReader 和 InputStreamReader)。
// 下面构造一个读取器对象。
BufferedReader br = new BufferedReader(new InputStreamReader(Systemin));
// 定义输入字符串
String inputStr = null;
// brreadLine():每当在键盘上输入一行内容按回车,刚输入的内容将被br(读取器对象)读取到。
// BufferedReader类的readLine方法:读取一个文本行。
// 初始状态由于无任何输入,brreadLine()会抛出异常。因而main方法要捕捉异常。
while ((inputStr = brreadLine()) != null) {
// 将用户输入的字符串以逗号(,)作为分隔符,分隔成2个字符串。
// String类的split方法,将会返回一个拆分后的字符串数组。
String[] posStrArr = inputStrsplit(",");
// 将2个字符串转换成用户下棋的坐标
int xPos = IntegerparseInt(posStrArr[0]);
int yPos = IntegerparseInt(posStrArr[1]);
// 校验用户下棋坐标的有效性,只能是数字,不能超出棋盘范围
if (xPos > 15 || xPos < 1 || yPos > 15 || yPos < 1) {
Systemoutprintln("您下棋的坐标值应在1到15之间,请重新输入!");
continue;
}
// 保证用户下的棋的坐标上不能已经有棋子(通过判断对应数组元素只能是"╋"来确定)
// String类的equals方法:比较字符串和指定对象是否相等。结果返回true或false。
if (gbboard[xPos - 1][yPos - 1]equals("╋")) {
// 把对应的数组元素赋为"●"。
gbboard[xPos - 1][yPos - 1] = "●";
} else {
Systemoutprintln("您下棋的点已有棋子,请重新输入!");
continue;
}
// 电脑下棋
gbcompPlay();
gbprintBoard();
// 每次下棋后,看是否可以断定赢/输了
if (gbjudgeWin() == false) {
Systemoutprintln("请输入您下棋的坐标,应以x,y的格式:");
} else {
// 完全跳出这个while循环,结束下棋
break;
}
}
}
}
界面思路:
用按钮数组模拟棋盘。
改变按钮的背景标志这个棋盘的格子上是黑棋、白棋、空。同时使用一个二维数组记录棋盘棋子的分布,比如qipan[0][0]=1标示第1行第一列的棋子是黑棋子,乙烯类推。
循环检测是否某行、某列、某斜线上是否已经有五个颜色相同的棋子。
简单的算法就是判断某行、某列、某斜线的妻子数目那个最多。通过2个for循环遍历棋盘。
复杂的算法,你看看下面的参考资料,不过下面这段材料如果看不懂的话,用简单的算法实现了五子棋也是很好的了,^_^
五子棋算法(AI)
任何一种棋类游戏其关键是对当前棋局是否有正确的评分,评分越准确则电脑的AI越高。五子棋游戏也是如此,但在打分之前,我们先扫描
整个棋盘,把每个空位从八个方向上的棋型填入数组gStyle(2, 15, 15, 8, 2),其中第一个下标为1时表示黑棋,为2时表示白棋,第二和第三
个下标表示(x,y),第四个下标表示8个方向,最后一个下标为1时表示棋子数,为2时表示空格数,如:
gStyle(1,2,2,1,1)=3表示与坐标(2,2)在第1个方向上相邻的黑棋棋子数为3
gstyle(1,2,2,1,2)=4表示与坐标(2,2)在第1个方向上的最近的空格数为4
在定义方向时,也应该注意一定的技巧,表示两个相反的方向的数应该差4,在程序中我是这样定义的:
Const DIR_UP = 1
Const DIR_UPRIGHT = 2
Const DIR_RIGHT = 3
Const DIR_RIGHTDOWN = 4
Const DIR_DOWN = 5
Const DIR_DOWNLEFT = 6
Const DIR_LEFT = 7
Const DIR_LEFTUP = 8
这样我们前四个方向可以通过加四得到另一个方向的值。如果你还是不太明白,请看下面的图:
---------
---------
---oo----
-oxxx---
---------
---------
图中的点从标为(4,4),(打的位置是空位),则:
gStyle(2,4,4,1,1)=1在(4,4)点相邻的上方白棋数为1
gStyle(2,4,4,1,2)=2在(4,4)点的上方距上方白棋最近的空格数为2
gStyle(1,4,4,3,1)=2在(4,4)点相邻的右方黑棋数为2
gStyle(1,4,4,3,2)=1在(4,4)点的右方距右方黑棋最近的空格数为3
一旦把所有空点的棋型值填完,我们很容易地得出黑棋水平方向上点(4,4)的价值,由一个冲1(我把有界的棋称为冲)和活2(两边无界的
棋称为活)组成的。对于而白棋在垂直方向上点(4,4)的价值是一个活1,而在/方向也是活1所以,只要我们把该点的对于黑棋和白棋的价值算出
来,然后我们就取棋盘上各个空点的这两个值的和的最大一点作为下棋的点。然而,对各种棋型应该取什么值呢?我们可以先作如下假设:
Fn 表示先手n个棋子的活棋型,如:F4表示先手活四
Fn'表示先手n个棋子的冲棋型,如:F4'表示先手冲四
Ln 表示后手n个棋子的活棋型,如:L3表示后手活三
Ln'表示后手n个棋子的冲棋型,如:L3'表示后手冲三
根据在一行中的棋型分析,得到如下关系:
L1'<=F1'<L2'<=F2'<=L1<F1<L2<F2<L3'<=F3'<L4'<F4'=F4
从这个关系包含了进攻和防守的关系(当然,这个关系是由我定的,你可以自己定义这些关系)。对这些关系再进一步细化,如在一个可下
棋的点,其四个方向上都有活三,也比不上一个冲四,所以我们可以又得到4F3<L4'这个关系,同样,我们还可以得到其它的关系,如:4F2<L3、4L3<F3,这些的关系由于你的定法和我的定法制可能不一样,这样计算机的AI也就不一样,最后我们把分值最小的L1'值定为1,则我们就得
到了下面各种棋型的分值,由C语言表示为:
F[2][5]={{0,2,5,50,16000},{0,10,30,750,16000}};
L[2][5]={{0,1,5,50,3750},{0,10,30,150,4000}};
F数组表示先手,第一个下标为0时表示冲型,第二个下标表示棋子数,则F2'对应F[0][2]L数组表示后手,第一个下标为0时表示冲型,第二
个下标表示棋子数,则L2对应F[1][2]Ok,棋型的分值关系确定好了以后,我们把每一个可下点的四个方向的棋型值相加(包括先手和后手的分
值),最后选择一个最大值,并把这一点作为计算机要下的点就OK了:)。
import javaawtButton;
import javaawtColor;
import javaawtGraphics;
import javaawteventActionEvent;
import javaawteventActionListener;
import javaawteventKeyAdapter;
import javaawteventKeyEvent;
import javaawteventMouseEvent;
import javaawteventMouseListener;
import javautilArrayList;
import javautilRandom;
import javaxswingBoxLayout;
import javaxswingJFrame;
import javaxswingJOptionPane;
import javaxswingJPanel;
import javaxswingTimer;
public class ChessGame extends JFrame implements MouseListener{
private int blackcount=0;
private int whitecount=0;
private boolean flag=true;
private boolean whitewin;
private boolean blackwin;
private boolean flash=false;
public Timer time;
private ArrayList<mypoint>blacklist;
private ArrayList<mypoint>whitelist;
public ChessGame(){
setSize(450,500);
setDefaultCloseOperation(JFrameEXIT_ON_CLOSE);
blacklist=new ArrayList<mypoint>();
whitelist=new ArrayList<mypoint>();
thisaddMouseListener(this);
setVisible(true);
}
@Override
public void paint(Graphics g) {
if(flash==true){
superpaint(g);
}
flash=false;
gsetColor(ColorWHITE);
gfillRect(0, 0, 420, 420);
gsetColor(ColorDARK_GRAY);
gdrawLine(5, 5, 420, 5);
gdrawLine(5, 5, 5, 420);
gdrawLine(420, 5, 420, 420);
gdrawLine(5, 420, 420, 420);
for(int i=1;i<=21;i++){
gdrawLine(5, 20i, 420, 20i);
gdrawLine(20i, 5, 20i, 420);
}
gsetColor(ColorBLACK);
for(int i=0;i<blacklistsize();i++){
gfillOval(blacklistget(i)getX()20+12,blacklistget(i)getY()20+32, 16, 16);
}
gsetColor(ColorRED);
for(int i=0;i<whitelistsize();i++){
gfillOval(whitelistget(i)getX()20+12,whitelistget(i)getY()20+32, 16, 16);
}
thischeckwin(blacklist, 0, 0, 0,0);
thischeckwin(whitelist, 0, 0, 0,1);
gsetColor(Colorblack);
String str1 = "黑方胜利局数为:" + blackcount;
gdrawString(str1, 10, 450);
String str2 = "红方胜利局数为:" + whitecount;
gdrawString(str2, 150, 450);
}
public static void main(String[] args){
ChessGame snake=new ChessGame();
}
public boolean checkExist(mypoint a){
for(int i=0;i<whitelistsize();i++){
if(whitelistget(i)getX()==agetX()&&whitelistget(i)getY()==agetY()){
return true;
}
}
for(int i=0;i<blacklistsize();i++){
if(blacklistget(i)getX()==agetX()&&blacklistget(i)getY()==agetY()){
return true;
}
}
return false;
}
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
double x=egetX();
double y=egetY();
if(x>=5&&x<=410&&y>=5&&y<=410){
double k=20;
x=x/k-1;
y=y/k-2;
int ax=(int) Mathround(x);
int ay=(int) Mathround(y);
if(checkExist(new mypoint(ax,ay))){
JOptionPaneshowMessageDialog(null, "该位置已有棋子!");
repaint();
}else{
if(flag==true){
blacklistadd(new mypoint(ax,ay));
}
if(flag==false){
whitelistadd(new mypoint(ax,ay));
}
flag=!flag;
repaint();
}
}
}
public void checkwin(ArrayList<mypoint> list,int pos,int direct,int count,int type){
if(count==0){
for(int i=0;i<listsize();i++){
for(int j=0;j<listsize();j++){
if(listget(i)getY()==listget(j)getY()&&(listget(j)getX()-listget(i)getX()==-1)){
direct=2;
count++;
checkwin(list,j,2,count,type);
count=0;
}
if(listget(i)getX()==listget(j)getX()&&(listget(j)getY()-listget(i)getY()==-1)){
direct=0;
count++;
checkwin(list,j,0,count,type);
count=0;
}
if(listget(j)getY()==listget(i)getY()-1&&(listget(j)getX()-listget(i)getX()==1)){
direct=4;
count++;
checkwin(list,j,4,count,type);
count=0;
}
if(listget(j)getY()==listget(i)getY()+1&&(listget(j)getX()-listget(i)getX()==1)){
direct=5;
count++;
checkwin(list,j,5,count,type);
count=0;
}
}
}
}
else{
if(direct==4){
for(int i=0;i<listsize();i++){
if(i!=pos){
if(listget(i)getX()==listget(pos)getX()+1&&(listget(i)getY()-listget(pos)getY()==-1)){
count=count+1;
if(count==4){
if(type==0){
Systemoutprintln("blackwin!");
blackcount++;
JOptionPaneshowMessageDialog(null, "黑方赢了!");
restart();
}if(type==1){
Systemoutprintln("whitewin!");
whitecount++;
JOptionPaneshowMessageDialog(null, "红方赢了!");
restart();
}
}else{
checkwin(list,i,direct,count,type);
}
}
}
}
}
if(direct==5){
for(int i=0;i<listsize();i++){
if(i!=pos){
if(listget(i)getX()==listget(pos)getX()+1&&(listget(i)getY()-listget(pos)getY()==1)){
count=count+1;
if(count==4){
if(type==0){
Systemoutprintln("blackwin!");
blackcount++;
JOptionPaneshowMessageDialog(null, "黑方赢了!");
restart();
}if(type==1){
Systemoutprintln("whitewin!");
whitecount++;
JOptionPaneshowMessageDialog(null, "红方赢了!");
restart();
}
}else{
checkwin(list,i,direct,count,type);
}
}
}
}
}
if(direct==0){
for(int i=0;i<listsize();i++){
if(i!=pos){
if(listget(pos)getX()==listget(i)getX()&&(listget(i)getY()-listget(pos)getY()==-1)){
count=count+1;
if(count==4){
if(type==0){
Systemoutprintln("blackwin!");
blackcount++;
JOptionPaneshowMessageDialog(null, "黑方赢了!");
restart();
}if(type==1){
Systemoutprintln("whitewin!");
whitecount++;
JOptionPaneshowMessageDialog(null, "红方赢了!");
restart();
}
}else{
checkwin(list,i,direct,count,type);
}
}
}
}
}
if(direct==2){
for(int i=0;i<listsize();i++){
if(i!=pos){
if(listget(pos)getY()==listget(i)getY()&&(listget(i)getX()-listget(pos)getX()==-1)){
count=count+1;
if(count==4){
if(type==0){
Systemoutprintln("blackwin!");
blackcount++;
JOptionPaneshowMessageDialog(null, "黑方赢了!");
restart();
}if(type==1){
Systemoutprintln("whitewin!");
whitecount++;
JOptionPaneshowMessageDialog(null, "红方赢了!");
restart();
}
}else{
checkwin(list,i,direct,count,type);
}
}
}
}
}
}
}
public void restart(){
whitelist=new ArrayList<mypoint>();
blacklist=new ArrayList<mypoint>();
flash=true;
repaint();
}
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
}
class mypoint{
int x;
int y;
public mypoint(int a,int b){
thisx=a;
thisy=b;
}
public int getX(){
return thisx;
}
public int getY(){
return thisy;
}
}
你的代码不全啊,代码太长了,打出来太多,你去找找《JAVA
面向对象程序设计》这本书,马迪芳、徐保民、陈旭东
三人编写的,316页往后就是介绍双人联机五子棋的源代码和注释
以上就是关于跪求JAVA五子棋源代码全部的内容,包括:跪求JAVA五子棋源代码、JAVA单机版五子棋怎么写、java编写五子棋程序,不要图形界面的那种等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)