📄 fivecanvas.java
字号:
import javax.microedition.lcdui.*;
import java.util.*;
public class FiveCanvas extends Canvas implements CommandListener {
public Graphics gg = null;
Random rnd = new Random();
public int lineNumber; // public int lineNumber = 11;
int gridWidth; // 格子的宽度
int gridHeight; // 格子的高度
int lineColor = 0x00006699; // 棋盘格子线的颜色
int focusColor = 0x0000ff00; // 焦点的颜色
public int intRunMode = 0; // 0-等待初始态,1-下棋,2-等待用户响应
public int intPlayer = 0; // 0-黑棋(先下者),1-白棋(后下者)
public int[] qipan;
// 检查后,如果不存在五子,则全为0,如果存在,则依次是五个子的位置
private int[] wuzi = new int[5];
private int[][] q;
private int[][] m;
int[] g = new int[4];
int baseX; // 棋盘左上角X
int baseY; // 棋盘左上角Y
int currentX; // 当前所在区域的左上角X
int currentY; // 当前所在区域的左上角Y
int currentA; // 当前是第几个竖线
int currentB; // 当前是第几个横线
int LastChessmanA; // 最后一个子位于第几根竖线
int LastChessmanB; // 最后一个子位于第几根横线
boolean loadedMenu = false;
Command cmdRestart = new Command("重新开始", Command.SCREEN, 1);
Command cmdExit = new Command("不玩了", Command.EXIT, 1);
// 设置一些棋盘参数
public void setParam(int[] value) {
lineNumber = value[0];
gridWidth = value[1];
gridHeight = value[2];
baseX = value[3];
baseY = value[4];
qipan = new int[lineNumber * lineNumber];
q = new int[3][lineNumber * lineNumber];
m = new int[3][lineNumber * lineNumber];
g[0] = 1;
g[1] = lineNumber;
g[2] = lineNumber - 1;
g[3] = lineNumber + 1;
}
public void paint(Graphics g) {
if (!loadedMenu) {
addCommand(cmdExit);
addCommand(cmdRestart);
setCommandListener(this);
loadedMenu = true;
}
if (gg == null)
gg = g;
if (intRunMode == 0)
buildChessboard();
}
// 事件处理函数
public void commandAction(Command c, Displayable s) {
if (!c.getLabel().equals("重新开始")) {
removeCommand(c);
addCommand(cmdRestart);
addCommand(cmdExit);
}
if (c.getCommandType() == Command.SCREEN) {
intRunMode = 0;
repaint();
} else if (c.getCommandType() == Command.EXIT) {
// 返回主界面
intRunMode = 0;
five.flow(1);
}
}
/**
* 开始游戏时所做的一些工作:比如画棋盘,初始化一些参数、数组,并设置最开始时的焦点位置
*/
public void buildChessboard() {
try {
// 初始化数组
for (int i = 0; i < lineNumber * lineNumber; i++) {
qipan[i] = 0;
for (int j = 0; j < 3; j++) {
q[j][i] = 0;
m[j][i] = 0;
}
}
for (int i = 0; i < 5; i++)
wuzi[i] = 0;
gg.setColor(0x006699cc);
gg.fillRect(0, 0, getWidth(), getHeight());
gg.setColor(lineColor);
for (int i = 1; i < lineNumber + 1; i++) {
gg.drawLine(gridWidth, i * gridHeight, gridWidth * lineNumber + 1, i * gridHeight);
gg.drawLine(i * gridWidth, gridHeight, i * gridWidth, lineNumber * gridHeight + 1);
}
// 初始时在中间
if (lineNumber % 2 == 0) {
currentX = baseX + gridWidth * (lineNumber / 2 - 1) - gridWidth / 2;
currentY = baseY + gridHeight * (lineNumber / 2 - 1) - gridHeight / 2;
currentA = lineNumber / 2;
} else {
currentX = baseX + gridWidth * (lineNumber - 1) / 2 - gridWidth / 2;
currentY = baseY + gridHeight * (lineNumber - 1) / 2 - gridHeight / 2;
currentA = (lineNumber + 1) / 2;
}
currentB = currentA;
intRunMode = 1;
intPlayer = 0;
moveFoucs(currentX - gridWidth / 2, currentY - gridHeight / 2 - 1, gridWidth * 3,
gridHeight * 2);
} catch (Exception e) {
System.out.println("buildChessboard Error:" + e);
}
}
/**
* 移动焦点,需要对六个格子大的范围进行重画(可以优化为两个格子) 重画内容包括六个棋盘格子, 十二个可能存在的棋子,以及一个焦点
*/
public void moveFoucs(int x, int y, int width, int height) {
try {
gg.setColor((rnd.nextInt() & 0x7FFFFFFF) % 256, (rnd.nextInt() & 0x7FFFFFFF) % 256,
(rnd.nextInt() & 0x7FFFFFFF) % 256);
gg.setColor(0x006699cc);
gg.fillRect(x, y, width, height);
// 这六个格子可能是横着的,也可能是竖的,其中有四个格子的位置是不变的
mydrawRect(x, y, gridWidth, gridHeight);
mydrawRect(x, y + gridHeight, gridWidth, gridHeight);
mydrawRect(x + gridWidth, y, gridWidth, gridHeight);
mydrawRect(x + gridWidth, y + gridHeight, gridWidth, gridHeight);
if (width > height) {
mydrawRect(x + gridWidth * 2, y, gridWidth, gridHeight);
mydrawRect(x + gridWidth * 2, y + gridHeight, gridWidth, gridHeight);
// 最右边的竖线
DrawChessman(x + gridWidth * 3, y);
DrawChessman(x + gridWidth * 3, y + gridHeight);
DrawChessman(x + gridWidth * 3, y + gridHeight * 2);
// 最下面的横线
DrawChessman(x, y + gridHeight * 2);
DrawChessman(x + gridWidth, y + gridHeight * 2);
DrawChessman(x + gridWidth * 2, y + gridHeight * 2);
} else {
mydrawRect(x, y + gridHeight * 2, gridWidth, gridHeight);
mydrawRect(x + gridWidth, y + gridHeight * 2, gridWidth, gridHeight);
// 最右边的竖线
DrawChessman(x + gridWidth * 2, y);
DrawChessman(x + gridWidth * 2, y + gridHeight);
DrawChessman(x + gridWidth * 2, y + gridHeight * 2);
DrawChessman(x + gridWidth * 2, y + gridHeight * 3);
// 最下面的横线
DrawChessman(x, y + gridHeight * 3);
DrawChessman(x + gridWidth, y + gridHeight * 3);
}
gg.setColor(focusColor);
// 画光标
int offsetValue = 1;
int offsetBase = 5;
gg.drawLine(currentX, currentY, currentX + gridWidth * offsetValue / offsetBase,
currentY);
gg.drawLine(currentX + gridWidth * (offsetBase - offsetValue) / offsetBase, currentY,
currentX + gridWidth, currentY);
gg.drawLine(currentX, currentY, currentX, currentY + gridHeight * offsetValue
/ offsetBase);
gg.drawLine(currentX, currentY + gridHeight * (offsetBase - offsetValue) / offsetBase,
currentX, currentY + gridHeight);
gg.drawLine(currentX + gridWidth, currentY, currentX + gridWidth, currentY + gridHeight
* offsetValue / offsetBase);
gg.drawLine(currentX + gridWidth, currentY + gridHeight * (offsetBase - offsetValue)
/ offsetBase, currentX + gridWidth, currentY + gridHeight);
gg.drawLine(currentX, currentY + gridHeight, currentX + gridWidth * offsetValue
/ offsetBase, currentY + gridHeight);
gg.drawLine(currentX + gridWidth * (offsetBase - offsetValue) / offsetBase, currentY
+ gridHeight, currentX + gridWidth, currentY + gridHeight);
repaint();
} catch (Exception e) {
System.out.println("moveFoucs Error:" + e);
}
}
/*
* 画格子,并画棋子。把这部分独立出来主要是要检查边界问题。 x 格子右上角x ,y 格子右上角y ,width 格子宽度 ,height 格子高度
*/
private void mydrawRect(int x, int y, int width, int height) {
int a, b;
a = (x - baseX) / gridWidth + 1;
b = (y - baseY) / gridHeight + 1;
if (a < 1 || b < 1 || a > lineNumber || b > lineNumber)
return;
if (a != lineNumber && b != lineNumber) {
gg.setColor(lineColor);
gg.drawRect(x, y + 1, width, height);
}
DrawChessman(x, y);
}
/*
* 画棋子,x,y分别是圆的中心坐标,棋子的直径为格子边长(格子应为正方形)的4/5
*/
public void DrawChessman(int x, int y) {
try {
int a;
int b;
a = (x - baseX) / gridWidth + 1;
b = (y - baseY) / gridHeight + 1;
if (a > lineNumber || a < 1 || b > lineNumber || b < 1)
return;
if (qipan[(b - 1) * lineNumber + a - 1] == 1)
gg.setColor(0, 0, 0);
else if (qipan[(b - 1) * lineNumber + a - 1] == 2)
gg.setColor(255, 255, 255);
else
return;
gg.fillArc(x - gridWidth * 2 / 5, y - gridHeight * 2 / 5, gridWidth * 4 / 5,
gridHeight * 4 / 5, 0, 360);
if (LastChessmanA == a && LastChessmanB == b) {
gg.setColor(0x00ff0000);
gg.drawLine(x, y - gridHeight / 5, x, y + gridHeight / 5);
gg.drawLine(x - gridWidth / 5, y, x + gridWidth / 5, y);
}
repaint();
} catch (Exception e) {
System.out.println("DrawChessman Error:" + e);
}
}
/*
* 键盘被按下。主要是移动焦点,以及落子的处理
*/
protected void keyPressed(int keyCode) {
if (intRunMode != 1)
return;
switch (getGameAction(keyCode)) {
case Canvas.LEFT:
if (currentX < baseX)
return;
currentX = currentX - gridWidth;
currentA--;
moveFoucs(currentX - gridWidth / 2, currentY - gridHeight / 2, gridWidth * 3,
gridHeight * 2);
break;
case Canvas.RIGHT:
if (currentX > baseX + gridWidth * (lineNumber - 2))
return;
currentX = currentX + gridWidth;
currentA++;
moveFoucs(currentX - gridWidth * 3 / 2, currentY - gridHeight / 2, gridWidth * 3,
gridHeight * 2);
break;
case Canvas.UP:
if (currentY < baseY)
return;
currentY = currentY - gridHeight;
currentB--;
moveFoucs(currentX - gridWidth / 2, currentY - gridHeight / 2, gridWidth * 2,
gridHeight * 3);
break;
case Canvas.DOWN:
if (currentY > baseY + gridHeight * (lineNumber - 2))
return;
currentY = currentY + gridHeight;
currentB++;
moveFoucs(currentX - gridWidth / 2, currentY - gridHeight * 3 / 2, gridWidth * 2,
gridHeight * 3);
break;
case Canvas.FIRE:
if (intPlayer == 0) {
int gotoValue;
if (qipan[lineNumber * (currentB - 1) + currentA - 1] != 0) {
System.out.println("此处有子");
return;
}
qipan[lineNumber * (currentB - 1) + currentA - 1] = 1;
DrawChessman(currentX + gridWidth / 2, currentY + gridHeight / 2);
gotoValue = tk();
// 检查人是否胜利
if (checkVictory())
return;
// 模拟电脑下一个
intPlayer = 1;
int a = currentA;
int b = currentB;
qipan[gotoValue] = 2;
a = LastChessmanA;
b = LastChessmanB;
LastChessmanA = (gotoValue + 1) % lineNumber;
LastChessmanB = (gotoValue + 1 - LastChessmanA) / lineNumber + 1;
DrawChessman((a - 1) * gridWidth + baseX, (b - 1) * gridHeight + baseY);
DrawChessman((LastChessmanA - 1) * gridWidth + baseX, (LastChessmanB - 1)
* gridHeight + baseY);
tk();
checkVictory();
// 准备人下
intPlayer = 0;
break;
}
}
}
/**
* 分析当前是否有一方胜利。并找出下一步该走在何处
*/
private int tk() {
try {
int[] e = { 1, 2, 4, 12, 24 };
int[] c = new int[3];
int g_b = 0; // 此变量记录电脑应下于何处
int n = 0;
int p;
int a0;
int h;
int a;
int d = 0;
int z = 0;
for (p = 0; p < 3; p++) { // 对两个大数组清零
for (a0 = 0; a0 < lineNumber * lineNumber; a0++) {
q[p][a0] = 0;
m[p][a0] = 0;
}
}
for (a0 = 0; a0 < lineNumber * lineNumber; a0++) {
for (d = 0; d < 4; d++) {
if ((a0 / lineNumber < (lineNumber - 4) || d == 0)
&& (a0 % lineNumber < (lineNumber - 4) || d == 1 || d == 2)
&& (a0 % lineNumber > 3 || d != 2)) {
c[1] = 0;
c[2] = 0;
for (z = 0; z < 5; z++) {
c[qipan[a0 + z * g[d]]]++;
}
if (c[1] == 0)
p = 2;
else if (c[2] == 0)
p = 1;
else
p = 0;
if (p != 0) {
for (z = 0; z < 5; z++) {
if (c[p] == 5)
// 记录五个子的坐标
wuzi[z] = a0 + z * g[d];
else if (qipan[a0 + z * g[d]] == 0) {
a = a0 + z * g[d];
q[0][a] += e[c[p]];
if (c[p] >= 2)
q[p][a] += e[c[p]];
if (c[p] > m[p][a])
m[p][a] = c[p];
}
}
}
}
}
for (p = 1; p < 3; p++)
if (q[p][a0] >= e[4]) {
h = 2 * m[p][a0];
if (p == 2)
h++;
if (q[0][a0] < lineNumber * lineNumber)
q[0][a0] += lineNumber * lineNumber * h;
else if (q[0][a0] < lineNumber * lineNumber * h)
q[0][a0] = lineNumber * lineNumber * h;
}
if (q[0][a0] > q[0][g_b])
n = 0;
if (q[0][a0] >= q[0][g_b]) {
n++;
if ((rnd.nextInt() & 0x7FFFFFFF) % 1000 * n / 1000 < 1)
g_b = a0;
}
}
return g_b;
} catch (Exception e) {
System.out.println("tk Error:" + e);
return 0;
}
}
// 检查是否有一方胜出,并做出相应处理
private boolean checkVictory() {
if (wuzi[1] != 0) { // WuZi[1]!=0表示已经大到5个了,一方胜利
intRunMode = 2;
String ShowString;
if (intPlayer == 0)
ShowString = "你赢了!";
else
ShowString = "电脑赢了!";
gg.drawString(ShowString, baseX, baseY, Graphics.TOP | Graphics.LEFT);
return true;
} else {
return false;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -