📄 tictactoe.java
字号:
} catch (IOException ex) {
notImage = null;
crossImage = null;
}
}
/**
* Paint it.
*/
public void paint(Graphics g) {
if (alerted) {
midlet.destroyApp(true);
midlet.notifyDestroyed();
return;
}
if (notImage == null || crossImage == null) {
showAlert("TicTacToe",
"Fatal error: could not load images",
AlertType.ERROR,
Alert.FOREVER,
this);
alerted = true;
return;
}
computeMessage();
g.setColor(255, 255, 255);
g.fillRect(0, 0, width, fullheight);
g.setColor(0, 0, 0);
g.drawString(midlet.message, 0, height,
Graphics.LEFT|Graphics.TOP);
int xoff = width / 3;
int yoff = height / 3;
g.drawLine(xoff, 0, xoff, height);
g.drawLine(2*xoff, 0, 2*xoff, height);
g.drawLine(0, yoff, width, yoff);
g.drawLine(0, 2*yoff, width, 2*yoff);
int i = 0;
for (int r = 0 ; r < 3 ; r++) {
for (int c = 0 ; c < 3 ; c++, i++) {
if ((midlet.peer & (1 << i)) != 0) {
g.drawImage(notImage,
c*xoff + 1 + xoff/2,
r*yoff + 1 + yoff/2,
Graphics.VCENTER|Graphics.HCENTER);
} else if ((midlet.you & (1 << i)) != 0) {
g.drawImage(crossImage,
c*xoff + 1 + xoff/2,
r*yoff + 1 + yoff/2,
Graphics.VCENTER|Graphics.HCENTER);
}
}
}
}
/**
* Compute the status message depending upon the game state.
*/
private void computeMessage() {
midlet.message = "JXTA TicTacToe";
switch (midlet.gameState) {
case STATE_NOT_CONNECTED:
midlet.message = "Waiting to connect";
break;
case STATE_WAITING_FOR_OPPONENT:
midlet.message = "Waiting for opponent";
break;
case STATE_PLAYING:
if (midlet.myMove) {
midlet.message = "Playing " + midlet.opponent;
} else {
midlet.message = "Awaiting " + midlet.opponent;
}
break;
case STATE_OBSERVING:
midlet.message = "Observing";
break;
case STATE_GAME_OVER:
midlet.message = "Game over";
break;
case STATE_WIN:
midlet.message = "You win!";
break;
case STATE_LOSE:
midlet.message = "You lose!";
break;
case STATE_STALEMATE:
midlet.message = "Stalemate!";
break;
case STATE_INVALID:
midlet.message = "Invalid move";
break;
}
repaint();
}
/**
* Reset the game.
*/
private void reset() {
midlet.peer = midlet.you = 0;
midlet.gameState = STATE_PLAYING;
repaint();
}
/**
* The user has pressed a key. Figure out which one
* and see if a legal move is possible. If it is a legal
* move, respond with a legal move (if possible).
*/
public void keyPressed(int keyCode) {
switch (midlet.status()) {
case WIN:
case LOSE:
case STALEMATE:
reset();
return;
}
if (keyCode < KEY_NUM1 || keyCode > KEY_NUM9) {
// not a game key, ignore
return;
}
if (!midlet.myMove) {
showAlert(TITLE_NAME,
"Not your move. Waiting for " + midlet.opponent,
AlertType.ERROR,
ALERT_TIMEOUT,
this);
return;
}
midlet.myMove = !midlet.myMove;
// Figure out the row/column
keyCode -= KEY_NUM1;
int c = keyCode % 3;
int r = keyCode / 3;
if (midlet.yourMove(c + r * 3)) {
switch (midlet.status()) {
case WIN:
midlet.gameState = STATE_LOSE;
// loser gets to play first in the next game
midlet.first = true;
break;
case LOSE:
midlet.gameState = STATE_WIN;
// loser gets to play first in the next game
midlet.first = false;
break;
case STALEMATE:
midlet.gameState = STATE_STALEMATE;
midlet.first = !midlet.first;
break;
}
} else {
midlet.gameState = STATE_INVALID;
}
midlet.send();
repaint();
}
}
public void run() {
while (!stopPolling) {
poll();
try {
// poll interval is specified in seconds
Thread.currentThread().sleep(config.getPollInterval() * 1000);
} catch (InterruptedException ignore) {
}
}
}
private synchronized boolean connect() {
String host = config.getRelayHost();
int port = 0;
try {
port = Integer.parseInt(config.getRelayPort());
} catch (NumberFormatException ex) {
showAlert("Connect",
"Error parsing relay port number: " +
config.getRelayPort(),
AlertType.ERROR,
Alert.FOREVER,
canvas);
return false;
}
String url = "http://" + host + ":" + port;
PeerNetwork pn = PeerNetwork.createInstance(config.getIdentity());
if (DEBUG) {
System.out.println("Connecting to " + url + "...");
}
try {
state = pn.connect(url, state);
pn.listen(PIPE_NAME, PIPE_ID, "JxtaPropagate");
} catch (IOException ex) {
showAlert("Connect",
"Error connecting to relay: " + ex.getMessage(),
AlertType.ERROR,
Alert.FOREVER,
canvas);
return false;
}
if (DEBUG) {
System.out.println("Connected");
}
peerNet = pn;
gameState = STATE_WAITING_FOR_OPPONENT;
send();
Thread incomingThread = new Thread(this);
incomingThread.start();
display.setCurrent(canvas);
return true;
}
private void send() {
if (peerNet == null) {
if (!connect()) {
return;
}
}
TicTacToeMessage t3msg =
new TicTacToeMessage(gameState, peer, you, config.getIdentity());
if (DEBUG) {
System.out.println(">> " + t3msg);
}
try {
Element[] elm = new Element[2];
elm[0] = new Element(ELEMENT_NAME,
t3msg.toBytes(),
null, null);
elm[1] = new Element("GrpName",
"NetPeerGroup".getBytes(),
null, null);
Message msg = new Message(elm);
peerNet.send(PIPE_NAME, PIPE_ID, "JxtaPropagate", msg);
} catch (IOException ex) {
showAlert("Send",
"Error sending message: " + ex.getMessage(),
AlertType.ERROR,
ALERT_TIMEOUT,
canvas);
return;
}
display.setCurrent(canvas);
}
private void poll() {
if (peerNet == null) {
if (!connect()) {
return;
}
}
Message msg = null;
try {
// timeout must not be zero: zero means block forever
msg = peerNet.poll(1);
} catch (IOException ex) {
showAlert("Poll",
"Error polling relay: " + ex.getMessage(),
AlertType.ERROR,
ALERT_TIMEOUT,
canvas);
return;
}
if (msg == null) {
return;
}
Element el = null;
TicTacToeMessage t3msg = null;
for (int i=0; i < msg.getElementCount(); i++) {
el = msg.getElement(i);
if (ELEMENT_NAME.equals(el.getName())) {
try {
t3msg = new TicTacToeMessage(el.getData());
} catch (IOException ex) {
if (DEBUG) {
System.err.println("Error reading message: " + ex);
}
}
}
}
if (t3msg == null) {
return;
}
if (t3msg.getSender().equals(config.getIdentity())) {
return;
}
if (DEBUG) {
System.out.println("<< " + t3msg);
}
int peerGameState = t3msg.getState();
if (gameState == STATE_WAITING_FOR_OPPONENT &&
peerGameState == STATE_WAITING_FOR_OPPONENT) {
opponent = t3msg.getSender();
gameState = STATE_PLAYING;
send();
} else if (gameState == STATE_WAITING_FOR_OPPONENT &&
peerGameState == STATE_PLAYING) {
opponent = t3msg.getSender();
gameState = STATE_PLAYING;
send();
} else if (gameState == STATE_PLAYING) {
you = t3msg.getPeerBoard();
peer = t3msg.getSenderBoard();
myMove = !myMove;
}
switch (status()) {
case WIN: gameState = STATE_LOSE; break;
case LOSE: gameState = STATE_WIN; break;
case STALEMATE: gameState = STATE_STALEMATE; break;
}
canvas.repaint();
}
static void showAlert(String title, String message, AlertType type,
int timeout, Displayable back) {
Alert alert = new Alert(title, message, null, type);
alert.setTimeout(timeout);
display.setCurrent(alert, back);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -