欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android實(shí)現(xiàn)中國象棋游戲(局域網(wǎng)版)

 更新時間:2022年05月10日 09:49:52   作者:hellolxb  
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)局域網(wǎng)版的中國象棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了Android實(shí)現(xiàn)中國象棋游戲的具體代碼,供大家參考,具體內(nèi)容如下

實(shí)現(xiàn)環(huán)境:  android studio 3.2.1, 手機(jī)分辨率為: 1920 * 1080

局域網(wǎng) UDP 連接
分主活動類,棋類,主機(jī)類

代碼如下:

清單文件要添加的權(quán)限:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />

主活動:

package chinachess;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

? ? private TextView tvMyIp;
? ? private EditText editIp;
? ? private EditText editReceiverPort;
? ? private EditText editSendrPort;
? ? private Button btnConn;
? ? private TextView tvTitle;
? ? private TextView tvTitle2;
? ? private TextView tvTitle3;

? ? @Override
? ? protected void onCreate(@Nullable Bundle savedInstanceState) {
? ? ? ? super.onCreate(savedInstanceState);
? ? ? ? setContentView(R.layout.activity_main);
? ? ? ? initView();
? ? }

? ? private void initView() {
? ? ? ? tvMyIp = (TextView) findViewById(R.id.tvMyIp);
? ? ? ? editIp = (EditText) findViewById(R.id.editIp);
? ? ? ? editReceiverPort = (EditText) findViewById(R.id.editReceiverPort);
? ? ? ? editSendrPort = (EditText) findViewById(R.id.editSendrPort);
? ? ? ? btnConn = (Button) findViewById(R.id.btnConn);
? ? ? ? btnConn.setOnClickListener(this);
? ? ? ? tvTitle = (TextView) findViewById(R.id.tvTitle);
? ? ? ? tvTitle2 = (TextView) findViewById(R.id.tvTitle2);
? ? ? ? tvTitle3 = (TextView) findViewById(R.id.tvTitle3);
? ? ? ? getIp();
? ? }
? ? // 將用于連接的控件隱藏掉
? ? public void uiGone() {
? ? ? ? tvMyIp.setVisibility(View.GONE);
? ? ? ? editIp.setVisibility(View.GONE);
? ? ? ? editReceiverPort.setVisibility(View.GONE);
? ? ? ? editSendrPort.setVisibility(View.GONE);
? ? ? ? btnConn.setVisibility(View.GONE);
? ? ? ? btnConn.setVisibility(View.GONE);
? ? ? ? tvTitle.setVisibility(View.GONE);
? ? ? ? tvTitle2.setVisibility(View.GONE);
? ? ? ? tvTitle3.setVisibility(View.GONE);
? ? }
? ? // 獲取局域網(wǎng) ip 的方法
? ? private void getIp() {
? ? ? ? String s;
? ? ? ? try {
? ? ? ? ? ? for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
? ? ? ? ? ? ? ? NetworkInterface face = en.nextElement();
? ? ? ? ? ? ? ? for (Enumeration<InetAddress> enAddr = face.getInetAddresses(); enAddr.hasMoreElements(); ){
? ? ? ? ? ? ? ? ? ? InetAddress addr = enAddr.nextElement();
? ? ? ? ? ? ? ? ? ? if (!addr.isLoopbackAddress()) {
? ? ? ? ? ? ? ? ? ? ? ? s = addr.getHostAddress();
? ? ? ? ? ? ? ? ? ? ? ? // 只獲取區(qū)域網(wǎng) ip 地址
? ? ? ? ? ? ? ? ? ? ? ? if ("192".equals(s.substring(0, 3))) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? tvMyIp.setText("IP: " + s);
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? } catch (SocketException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? }

? ? @Override
? ? public void onClick(View v) {
? ? ? ? switch (v.getId()) {
? ? ? ? ? ? case R.id.btnConn:
? ? ? ? ? ? ? ? submit();
? ? ? ? ? ? ? ? break;
? ? ? ? }
? ? }

? ? private void submit() {
? ? ? ? // validate
? ? ? ? String ip = editIp.getText().toString().trim();
? ? ? ? if (TextUtils.isEmpty(ip)) {
? ? ? ? ? ? Toast.makeText(this, "IP不可為空!", Toast.LENGTH_SHORT).show();
? ? ? ? ? ? return;
? ? ? ? }

? ? ? ? String receiverPort = editReceiverPort.getText().toString().trim();
? ? ? ? if (TextUtils.isEmpty(receiverPort)) {
? ? ? ? ? ? Toast.makeText(this, "接收端口不可為空!", Toast.LENGTH_SHORT).show();
? ? ? ? ? ? return;
? ? ? ? }

? ? ? ? String sendPort = editSendrPort.getText().toString().trim();
? ? ? ? if (TextUtils.isEmpty(sendPort)) {
? ? ? ? ? ? Toast.makeText(this, "發(fā)送端口不可為空!", Toast.LENGTH_SHORT).show();
? ? ? ? ? ? return;
? ? ? ? }

? ? ? ? // TODO validate success, do something
? ? ? ? // 開啟服務(wù)器或客戶端,并添加到主活動中
? ? ? ? ServerView server = new ServerView(this, Integer.valueOf(receiverPort), Integer.valueOf(sendPort), ip);
? ? ? ? ViewGroup.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
? ? ? ? addContentView(server, params);
? ? ? ? server.startServer();
? ? }
}

布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
? ? xmlns:app="http://schemas.android.com/apk/res-auto"
? ? xmlns:tools="http://schemas.android.com/tools"
? ? android:layout_width="match_parent"
? ? android:layout_height="match_parent"
? ? android:orientation="vertical"
? ? android:padding="5dp"
? ? tools:context=".MainActivity">

? ? <TextView
? ? ? ? android:id="@+id/tvTitle"
? ? ? ? android:layout_width="match_parent"
? ? ? ? android:layout_height="wrap_content"
? ? ? ? android:text="UDP"
? ? ? ? android:textColor="#000"
? ? ? ? android:textSize="22dp" />

? ? <TextView
? ? ? ? android:id="@+id/tvMyIp"
? ? ? ? android:layout_width="match_parent"
? ? ? ? android:layout_height="wrap_content"
? ? ? ? android:text="IP"
? ? ? ? android:textColor="#000"
? ? ? ? android:textSize="18sp" />

? ? <EditText
? ? ? ? android:id="@+id/editIp"
? ? ? ? android:layout_width="match_parent"
? ? ? ? android:layout_height="wrap_content"
? ? ? ? android:hint="IP"
? ? ? ? android:text="192.168."
? ? ? ? android:textColor="#000" />

? ? <LinearLayout
? ? ? ? android:layout_width="match_parent"
? ? ? ? android:layout_height="wrap_content"
? ? ? ? android:gravity="center">

? ? ? ? <TextView
? ? ? ? ? ? android:id="@+id/tvTitle2"
? ? ? ? ? ? android:textSize="18sp"
? ? ? ? ? ? android:textColor="#000"
? ? ? ? ? ? android:layout_width="wrap_content"
? ? ? ? ? ? android:layout_height="wrap_content"
? ? ? ? ? ? android:text="接收端口: " />

? ? ? ? <EditText
? ? ? ? ? ? android:id="@+id/editReceiverPort"
? ? ? ? ? ? android:layout_width="0dp"
? ? ? ? ? ? android:layout_weight="1"
? ? ? ? ? ? android:layout_height="wrap_content"
? ? ? ? ? ? android:hint="IP"
? ? ? ? ? ? android:inputType="number"
? ? ? ? ? ? android:text="10001"
? ? ? ? ? ? android:textColor="#000" />

? ? ? ? <TextView
? ? ? ? ? ? android:id="@+id/tvTitle3"
? ? ? ? ? ? android:textSize="18sp"
? ? ? ? ? ? android:textColor="#000"
? ? ? ? ? ? android:layout_width="wrap_content"
? ? ? ? ? ? android:layout_height="wrap_content"
? ? ? ? ? ? android:text="發(fā)送端口: " />

? ? ? ? <EditText
? ? ? ? ? ? android:id="@+id/editSendrPort"
? ? ? ? ? ? android:layout_width="0dp"
? ? ? ? ? ? android:layout_weight="1"
? ? ? ? ? ? android:layout_height="wrap_content"
? ? ? ? ? ? android:hint="IP"
? ? ? ? ? ? android:inputType="number"
? ? ? ? ? ? android:text="10000"
? ? ? ? ? ? android:textColor="#000" />

? ? </LinearLayout>

? ? <Button
? ? ? ? android:id="@+id/btnConn"
? ? ? ? android:textSize="18sp"
? ? ? ? android:textStyle="bold"
? ? ? ? android:textColor="#FFF5C3"
? ? ? ? android:text="連接"
? ? ? ? android:background="@drawable/btn_blue"
? ? ? ? android:layout_width="match_parent"
? ? ? ? android:layout_height="wrap_content" />

</LinearLayout>

btn_blue.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

? ? <corners android:radius="5dp" />

? ? <gradient android:startColor="#0000a1" android:centerColor="#1f6ed4"
? ? ? ? android:angle="315"
? ? ? ? android:endColor="#39BAE8" />

</shape>

棋類:

package chinachess;

public class Chess {
? ? // 標(biāo)記當(dāng)前棋的顏色是紅棋還是黑棋
? ? public static final int BLACK = 1;
? ? public static final int RED = 2;
? ? // 存儲當(dāng)前棋子是紅棋還是黑棋
? ? private int player;
? ? // 當(dāng)前棋子的名字
? ? private String name;
? ? // 圖片 id
? ? private int imageId;
? ? // 圖片編號
? ? // 0-15 紅色,16-31 黑色
? ? // 0-帥
? ? // 1,2-士
? ? // 3,4-相
? ? // 5,6-馬
? ? // 7,8-車
? ? // 9,10-炮
? ? // 11-15-卒
? ? // 16-黑帥
? ? // ...
? ? private int num;
? ? // 當(dāng)前棋在棋盤中的位置,posX 為行,posY 為列
? ? private int posX, posY;

? ? public Chess(int player, String name, int num) {
? ? ? ? this.player = player;
? ? ? ? this.name = name;
? ? ? ? this.num = num;
? ? ? ? // 紅旗的圖片 id
? ? ? ? int[] redId = {R.drawable.shuai, R.drawable.shi, R.drawable.xiang, R.drawable.ma, R.drawable.che,
? ? ? ? R.drawable.pao, R.drawable.bing};
? ? ? ? // 黑旗的圖片 id
? ? ? ? int[] blackId = {R.drawable.shuai1, R.drawable.shi1, R.drawable.xiang1, R.drawable.ma1, R.drawable.che1,
? ? ? ? ? ? ? ? R.drawable.pao1, R.drawable.bing1};
? ? ? ? // 所有的棋的種類
? ? ? ? String[] names = {"帥", "士", "相", "馬", "車", "炮", "卒"};
? ? ? ? // 根據(jù)當(dāng)前棋的顏色來匹配不同的圖片
? ? ? ? if (player == RED) {
? ? ? ? ? ? for (int i = 0; i < names.length; i++) {
? ? ? ? ? ? ? ? if (names[i].equals(name)) {
? ? ? ? ? ? ? ? ? ? imageId = redId[i];
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? } else {
? ? ? ? ? ? for (int i = 0; i < names.length; i++) {
? ? ? ? ? ? ? ? if (names[i].equals(name)) {
? ? ? ? ? ? ? ? ? ? imageId = blackId[i];
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? // 獲取棋編號
? ? public int getNum() {
? ? ? ? return num;
? ? }
? ? // 獲取棋的顏色
? ? public int getPlayer() {
? ? ? ? return player;
? ? }
? ? // 獲取棋名
? ? public String getName() {
? ? ? ? return name;
? ? }
? ? // 獲取棋的圖片id
? ? public int getImageId() {
? ? ? ? return imageId;
? ? }
? ? // 設(shè)置棋的行列坐標(biāo)
? ? public void setPos(int posX, int posY) {
? ? ? ? this.posX = posX;
? ? ? ? this.posY = posY;
? ? }
? ? // 設(shè)置棋的航坐標(biāo)
? ? public int getPosX() {
? ? ? ? return posX;
? ? }
? ? // 設(shè)置棋的列坐標(biāo)
? ? public int getPosY() {
? ? ? ? return posY;
? ? }
? ? // 將當(dāng)前的棋坐標(biāo)水平翻轉(zhuǎn)
? ? public void reverse() {
? ? ? ? posX = 9 - posX;
? ? }
}

主機(jī)類:
 

package chinachess;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

import chinachess.Chess;
import chinachess.MainActivity;
import com.example.l_b.chinachess.R;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class ServerView extends View {

?? ?// private static final String TAG = "qaq";
? ? // 棋的顏色
? ? public static final int BLACK = 1;
? ? public static final int RED = 2;
? ? // 設(shè)置棋盤的位置,視情況而定
? ? public static final int MARGINTOP = 150;
? ? public static final int MARGINLEFT = 83;
? ? // 每個格子的寬度
? ? public static final int W = 114;
? ? // 棋的總數(shù)
? ? public static final int ALLCHESS = 32;
? ? // 棋盤的行
? ? public static final int ROW = 10;
? ? // 棋盤的列
? ? public static final int COL = 9;
? ? // 沒有棋的棋盤坐標(biāo)的標(biāo)記
? ? public static final int NULL = -1;
? ? // 接受消息端口
? ? private int receiverPort;
? ? // 發(fā)送消息端口
? ? private int sendPort;
? ? // 對方 ip
? ? private String ip;
? ? // 主活動
? ? private MainActivity context;
? ? // 所有的棋
? ? private Chess[] allChess = new Chess[ALLCHESS];
? ? // 棋盤
? ? private int[][] map = new int[ROW][COL];
? ? // 當(dāng)前是否可以點(diǎn)擊
? ? private boolean canPlay;
? ? // 判斷是否移動了,只可處理點(diǎn)擊事件
? ? private boolean isMove;
? ? // 設(shè)置我方的棋的顏色
? ? private int player;
? ? // 記錄第一次選擇的棋
? ? private Chess firstSelect;
? ? // 用于提示消息
? ? private TextView tvTip;
? ? // 判斷當(dāng)前是否贏了
? ? private boolean isWin;
?? ?
?? ?private Button btnNewGame;
?? ?
? ? // 通過構(gòu)造方法將一些重要參數(shù)傳入進(jìn)來
? ? public ServerView(Context context, int receiverPort, int sendPort, String ip) {
? ? ? ? super(context);
? ? ? ? this.receiverPort = receiverPort;
? ? ? ? this.sendPort = sendPort;
? ? ? ? this.ip = ip;
? ? ? ? this.context = (MainActivity) context;
? ? ? ? // 添加一個可以重新開始的按鈕
? ? ? ? ViewGroup.LayoutParams param = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, 120);
? ? ? ? btnNewGame = new Button(context);
? ? ? ? // 開始游戲后才可以點(diǎn)擊
?? ??? ?btnNewGame。setEnabled(false);
? ? ? ? btnNewGame.setX(10);
? ? ? ? btnNewGame.setY(10);
? ? ? ? btnNewGame.setBackgroundResource(R.drawable.btn_blue);
? ? ? ? btnNewGame.setText("重新開始");
? ? ? ? btnNewGame.setTextColor(Color.WHITE);
? ? ? ? btnNewGame.setOnClickListener(new OnClickListener() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void onClick(View v) {
? ? ? ? ? ? ? ? // 重新開始游戲
? ? ? ? ? ? ? ? restartGame();
? ? ? ? ? ? ? ? sendMes("restart|");
? ? ? ? ? ? }
? ? ? ? });
? ? ? ? this.context.addContentView(btnNewGame, param);
? ? ? ? // 添加用于提示的文本框
? ? ? ? tvTip = new TextView(context);
? ? ? ? tvTip.setX(300);
? ? ? ? tvTip.setY(10);
? ? ? ? this.context.addContentView(tvTip, param);
? ? ? ? // 初始化棋盤
? ? ? ? initMapAndChess();
? ? ? ? // 設(shè)置觸屏事件
? ? ? ? setOnTouchListener(new OnTouchListener() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public boolean onTouch(View v, MotionEvent event) {
? ? ? ? ? ? ? ? // 若當(dāng)前不可以點(diǎn)擊則不執(zhí)行點(diǎn)擊事件
? ? ? ? ? ? ? ? if (!canPlay) {
? ? ? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? switch (event.getAction()) {
? ? ? ? ? ? ? ? ? ? case MotionEvent.ACTION_DOWN:
? ? ? ? ? ? ? ? ? ? ? ? isMove = false;
? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? case MotionEvent.ACTION_MOVE:
? ? ? ? ? ? ? ? ? ? ? ? // 若有滑動事件則會執(zhí)行
? ? ? ? ? ? ? ? ? ? ? ? isMove = true;
? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? case MotionEvent.ACTION_UP:
? ? ? ? ? ? ? ? ? ? ? ? if (!isMove) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? // 獲取點(diǎn)擊的 x 坐標(biāo)
? ? ? ? ? ? ? ? ? ? ? ? ? ? int x = ((int) event.getX() - MARGINLEFT);
? ? ? ? ? ? ? ? ? ? ? ? ? ? // 獲取點(diǎn)擊的 y 坐標(biāo)
? ? ? ? ? ? ? ? ? ? ? ? ? ? int y = ((int) event.getY() - MARGINTOP - MARGINLEFT);
? ? ? ? ? ? ? ? ? ? ? ? ? ? // 轉(zhuǎn)化為棋盤的 col 列坐標(biāo)
? ? ? ? ? ? ? ? ? ? ? ? ? ? // x % W > W / 2 ? 1 : 0 為當(dāng)前的位置的求模后是否滿足大于一半的寬度,
? ? ? ? ? ? ? ? ? ? ? ? ? ? // 若大于則把它安排到下一個位置,否則不變
? ? ? ? ? ? ? ? ? ? ? ? ? ? x = x / W + (x % W > W / 2 ? 1 : 0);
? ? ? ? ? ? ? ? ? ? ? ? ? ? // 轉(zhuǎn)化為棋盤的 row 行坐標(biāo)
? ? ? ? ? ? ? ? ? ? ? ? ? ? y = y / W + (y % W > W / 2 ? 1 : 0);
? ? ? ? ? ? ? ? ? ? ? ? ? ? // 若超出棋盤邊界則不執(zhí)行
? ? ? ? ? ? ? ? ? ? ? ? ? ? if (x < 0 || x >= COL || y < 0 || y >= ROW) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? // 如果為第一次點(diǎn)擊
? ? ? ? ? ? ? ? ? ? ? ? ? ? if (firstSelect == null) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 若當(dāng)前點(diǎn)擊的位置是空的
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (map[y][x] == NULL) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 創(chuàng)建一個臨時變量來存儲當(dāng)前位置上的棋
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Chess temp = allChess[map[y][x]];
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 若點(diǎn)擊的是對方的棋
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (temp.getPlayer() != player) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 存起來
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? firstSelect = temp;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 更新視圖
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? invalidate();
? ? ? ? ? ? ? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 已選擇第一個棋后
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 若當(dāng)前位置為空棋時
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (map[y][x] == NULL) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 若能移動
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (canMove(y, x)) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 獲取第一次選擇的棋的編號, 范圍為 0,1,2,3...31;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int pos = map[firstSelect.getPosX()][firstSelect.getPosY()];
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 將第一次選擇的棋編號給第二次選擇的位置
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? map[y][x] = pos;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 將第一次選擇的棋編號置空
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? map[firstSelect.getPosX()][firstSelect.getPosY()] = NULL;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 將第一次選擇的棋的位置改變?yōu)楫?dāng)前位置
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? firstSelect.setPos(y, x);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 輪到對方下
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? canPlay = false;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 將存儲的第一個棋置空
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? firstSelect = null;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 發(fā)送我方移動信息給客戶單,“|” 為分隔符,用于分割信息,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 最后要用 "|" 結(jié)尾,不然最后一個信息個出錯
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sendMes("move|" + pos + "|" + y + "|" + x + "|");
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 設(shè)置提示消息
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? tvTip.setText("對方下");
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 更新視圖
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? invalidate();
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 若當(dāng)前的位置不為空棋
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 獲取當(dāng)前的棋編號
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int pos = map[y][x];
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 若當(dāng)前的棋為我方棋時,則把第一次選擇的棋替換為當(dāng)前棋
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (allChess[pos].getPlayer() == player) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? firstSelect = allChess[pos];
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? invalidate();
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 是否可以移動
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (canMove(y, x)) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 將第一次選擇的棋編號置空
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? map[firstSelect.getPosX()][firstSelect.getPosY()] = NULL;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 將第一次選擇的棋編號給第二次選擇的位置
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? map[y][x] = firstSelect.getNum();
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 將第一次選擇的棋的位置改變?yōu)楫?dāng)前位置
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? firstSelect.setPos(y, x);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 發(fā)送我方移動信息給客戶單
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sendMes("move|" + firstSelect.getNum() + "|" + y + "|" + x + "|");
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 若當(dāng)前吃掉的棋為帥時
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if ("帥".equals(allChess[pos].getName())) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sendMes("winner|");
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? tvTip.setText("我方獲勝");
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? tvTip.setText("對方下");
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 將存儲的第一個棋置空
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? firstSelect = null;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 將吃掉得棋置空
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? allChess[pos] = null;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 輪到對方下
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? canPlay = false;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? invalidate();
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? }
? ? ? ? });
? ? }
?? ?// 判斷是否可以移動
? ? private boolean canMove(int r2, int c2) {
? ? ? ? // 要移動的棋名
? ? ? ? String name = firstSelect.getName();
? ? ? ? // 存儲第一次的行坐標(biāo)
? ? ? ? int r1 = firstSelect.getPosX();
? ? ? ? // 存儲第一次的列坐標(biāo)
? ? ? ? int c1 = firstSelect.getPosY();

? ? ? ? if ("帥".equals(name)) {
? ? ? ? ? ? // 只能直線移動
? ? ? ? ? ? if (r1 != r2 && c1 != c2) {
? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? }
? ? ? ? ? ? // 判斷是否可以將軍
? ? ? ? ? ? if (map[r2][c2] != NULL && "帥".equals(allChess[map[r2][c2]].getName())) {
? ? ? ? ? ? ? ? // 保持 r1 一定小于 r2
? ? ? ? ? ? ? ? // c1 一定等于 c2
? ? ? ? ? ? ? ? if (r1 > r2) {
? ? ? ? ? ? ? ? ? ? int t = r1;
? ? ? ? ? ? ? ? ? ? r1 = r2;
? ? ? ? ? ? ? ? ? ? r2 = t;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? // 標(biāo)記兩個帥之間是否有棋子,若有,則不可以移動
? ? ? ? ? ? ? ? boolean flag = true;
? ? ? ? ? ? ? ? for (int i = r1 + 1; i < r2 && flag; i++) {
? ? ? ? ? ? ? ? ? ? if (map[i][c1] != NULL) {
? ? ? ? ? ? ? ? ? ? ? ? flag = false;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? return flag;
? ? ? ? ? ? ? ? // 只可移動一格
? ? ? ? ? ? } else if (Math.abs(c1 - c2) != 1 && Math.abs(r2 - r1) != 1) {
? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? }
? ? ? ? ? ? // 只可在田字中移動
? ? ? ? ? ? return r2 >= 7 && c2 >= 3 && c2 <= 5;
? ? ? ? } else if ("士".equals(name)) {
? ? ? ? ? ? // 不能直線移動
? ? ? ? ? ? if (r1 == r2 || c1 == c2) {
? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? }
? ? ? ? ? ? // 只能移動一格
? ? ? ? ? ? if (Math.abs(r1 - r2) != 1 || Math.abs(c1 - c2) != 1) {
? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? }
? ? ? ? ? ? // 只可在田字中移動
? ? ? ? ? ? return r2 >= 7 && c2 >= 3 && c2 <= 5;
? ? ? ? } else if ("相".equals(name)) {
? ? ? ? ? ? // 不可以過河,越界
? ? ? ? ? ? if (r2 <= 4) {
? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? }
? ? ? ? ? ? // 只能走田字
? ? ? ? ? ? if (Math.abs(r1 - r2) != 2 || Math.abs(c1 - c2) != 2) {
? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? }
? ? ? ? ? ? // 是否被擋住了
? ? ? ? ? ? return map[(r1 + r2) / 2][(c1 + c2) / 2] == NULL;
? ? ? ? } else if ("馬".equals(name)) {
? ? ? ? ? ? // 只能走 日 字
? ? ? ? ? ? if (Math.abs(r1 - r2) * Math.abs(r1 - r2) + Math.abs(c1 - c2) * Math.abs(c1 - c2) != 5) {
? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? }
? ? ? ? ? ? // 向下走時
? ? ? ? ? ? if (r2 - r1 == 2) {
? ? ? ? ? ? ? ? // 是否被擋住了
? ? ? ? ? ? ? ? if (map[r1 + 1][c1] != NULL) {
? ? ? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? // 向上走時
? ? ? ? ? ? } else if (r2 - r1 == -2) {
? ? ? ? ? ? ? ? if (map[r1 - 1][c1] != NULL) {
? ? ? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? // 向左走時
? ? ? ? ? ? } else if (c2 - c1 == 2) {
? ? ? ? ? ? ? ? if (map[r1][c1 + 1] != NULL) {
? ? ? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? // 向右走時
? ? ? ? ? ? } else if (c2 - c1 == -2) {
? ? ? ? ? ? ? ? if (map[r1][c1 - 1] != NULL) {
? ? ? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? } else if ("車".equals(name)) {
? ? ? ? ? ? // 只能直線移動
? ? ? ? ? ? if (r2 != r1 && c2 != c1) {
? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? }
? ? ? ? ? ? // 一個臨時變量
? ? ? ? ? ? int t;
? ? ? ? ? ? // 左右走
? ? ? ? ? ? if (r2 == r1) {
? ? ? ? ? ? ? ? // 確保 c1 一定 小于 c2
? ? ? ? ? ? ? ? if (c1 > c2) {
? ? ? ? ? ? ? ? ? ? t = c1;
? ? ? ? ? ? ? ? ? ? c1 = c2;
? ? ? ? ? ? ? ? ? ? c2 = t;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? // 之間是否被擋住了
? ? ? ? ? ? ? ? for (int i = c1 + 1; i < c2; i++) {
? ? ? ? ? ? ? ? ? ? if (map[r1][i] != NULL) {
? ? ? ? ? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? // 上下走
? ? ? ? ? ? ? ? // 確保 r1 一定 小于 r2
? ? ? ? ? ? ? ? if (r1 > r2) {
? ? ? ? ? ? ? ? ? ? t = r1;
? ? ? ? ? ? ? ? ? ? r1 = r2;
? ? ? ? ? ? ? ? ? ? r2 = t;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? for (int i = r1 + 1; i < r2; i++) {
? ? ? ? ? ? ? ? ? ? if (map[i][c1] != NULL) {
? ? ? ? ? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? } else if ("炮".equals(name)) {
? ? ? ? ? ? // 只能走直線
? ? ? ? ? ? if (r1 != r2 && c1 != c2) {
? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? }
? ? ? ? ? ? int t;
? ? ? ? ? ? // 平常走時,跟車一樣
? ? ? ? ? ? if (map[r2][c2] == NULL) {
? ? ? ? ? ? ? ? if (r2 == r1) {
? ? ? ? ? ? ? ? ? ? // 確保 c1 一定在 c2 的上面
? ? ? ? ? ? ? ? ? ? if (c1 > c2) {
? ? ? ? ? ? ? ? ? ? ? ? t = c1;
? ? ? ? ? ? ? ? ? ? ? ? c1 = c2;
? ? ? ? ? ? ? ? ? ? ? ? c2 = t;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? for (int i = c1 + 1; i < c2; i++) {
? ? ? ? ? ? ? ? ? ? ? ? if (map[r1][i] != NULL) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? if (r1 > r2) {
? ? ? ? ? ? ? ? ? ? ? ? t = r1;
? ? ? ? ? ? ? ? ? ? ? ? r1 = r2;
? ? ? ? ? ? ? ? ? ? ? ? r2 = t;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? for (int i = r1 + 1; i < r2; i++) {
? ? ? ? ? ? ? ? ? ? ? ? if (map[i][c1] != NULL) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? // 可以吃子時
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? // 用于記錄之間有幾個棋子,只能為一
? ? ? ? ? ? ? ? int count = 0;
? ? ? ? ? ? ? ? if (r2 == r1) {
? ? ? ? ? ? ? ? ? ? // 確保 c1 一定在 c2 的上面
? ? ? ? ? ? ? ? ? ? if (c1 > c2) {
? ? ? ? ? ? ? ? ? ? ? ? t = c1;
? ? ? ? ? ? ? ? ? ? ? ? c1 = c2;
? ? ? ? ? ? ? ? ? ? ? ? c2 = t;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? for (int i = c1 + 1; i < c2; i++) {
? ? ? ? ? ? ? ? ? ? ? ? if (map[r1][i] != NULL) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? count++;
? ? ? ? ? ? ? ? ? ? ? ? ? ? if (count > 1) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? if (r1 > r2) {
? ? ? ? ? ? ? ? ? ? ? ? t = r1;
? ? ? ? ? ? ? ? ? ? ? ? r1 = r2;
? ? ? ? ? ? ? ? ? ? ? ? r2 = t;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? for (int i = r1 + 1; i < r2; i++) {
? ? ? ? ? ? ? ? ? ? ? ? if (map[i][c1] != NULL) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? count++;
? ? ? ? ? ? ? ? ? ? ? ? ? ? if (count > 1) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? if (count != 1) {
? ? ? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? } else if ("卒".equals(name)) {
? ? ? ? ? ? // 只能往前走
? ? ? ? ? ? if (r2 > r1) {
? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? }
? ? ? ? ? ? // 若過河了
? ? ? ? ? ? if (r1 <= 4) {
? ? ? ? ? ? ? ? // 只能走直線
? ? ? ? ? ? ? ? if (r2 != r1 && c2 != c1) {
? ? ? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? // 只能走一格
? ? ? ? ? ? ? ? if (Math.abs(c1 - c2) != 1 && r1 - r2 != 1) {
? ? ? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? // 若沒有過河,則只能前走一格
? ? ? ? ? ? ? ? if (c2 != c1 || r1 - r2 != 1) {
? ? ? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? return true;
? ? }

? ? private void initMapAndChess() {
? ? ? ? // 將編號全置空
? ? ? ? for (int i = 0; i < ROW; i++) {
? ? ? ? ? ? for (int j = 0; j < COL; j++) {
? ? ? ? ? ? ? ? map[i][j] = NULL;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? // 將,兩士,兩相,兩馬,兩車,兩炮,五卒
? ? ? ? // 32 個棋子在地圖上的 x 坐標(biāo),紅棋先
? ? ? ? // 前16個棋的 x 坐標(biāo)
? ? ? ? int[] mapX = {4, 3, 5, 2, 6, 1, 7, 0, 8, 1, 7, 0, 2, 4, 6, 8};
? ? ? ? // 前16個棋的 y 坐標(biāo)
? ? ? ? int[] mapY = {0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 3, 3, 3, 3, 3};
? ? ? ? // 前16個棋的棋名
? ? ? ? String[] strings = {"帥", "士", "士", "相", "相", "馬", "馬", "車", "車", "炮", "炮", "卒", "卒", "卒", "卒", "卒"};
? ? ? ? // 臨時存儲行和列
? ? ? ? int row, col;
? ? ? ? for (int i = 0; i < allChess.length; i++) {
? ? ? ? ? ? // 小于16為紅旗
? ? ? ? ? ? if (i < 16) {
? ? ? ? ? ? ? ? row = mapY[i];
? ? ? ? ? ? ? ? col = mapX[i];
? ? ? ? ? ? ? ? // 初始化棋子
? ? ? ? ? ? ? ? allChess[i] = new Chess(RED, strings[i], i);
? ? ? ? ? ? ? ? // 給相應(yīng)的棋盤位置安排編號
? ? ? ? ? ? ? ? map[row][col] = i;
? ? ? ? ? ? ? ? // 設(shè)置棋子在棋盤中的初始位置
? ? ? ? ? ? ? ? allChess[i].setPos(row, col);
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? row = ROW - mapY[i - 16] - 1;
? ? ? ? ? ? ? ? col = COL - mapX[i - 16] - 1;
? ? ? ? ? ? ? ? allChess[i] = new Chess(BLACK, strings[i - 16], i);
? ? ? ? ? ? ? ? map[row][col] = i;
? ? ? ? ? ? ? ? allChess[i].setPos(row, col);
? ? ? ? ? ? }
? ? ? ? }
// ? ? ? ?showChess();
? ? }

// ? ?private void showChess() {
// ? ? ? ?String s;
// ? ? ? ?for (int i = 0; i < ROW; i++) {
// ? ? ? ? ? ?s = "";
// ? ? ? ? ? ?for (int j = 0; j < COL; j++) {
// ? ? ? ? ? ? ? ?s += map[i][j] + " ";
// ? ? ? ? ? ?}
// ? ? ? ? ? ?Log.d(TAG, "showChess: " + s);
// ? ? ? ?}
// ? ? ? ?for (int i = 0; i < allChess.length; i++) {
// ? ? ? ? ? ?Log.d(TAG, "showChess: " + allChess[i].getName() + "-" + allChess[i].getNum() + "-" + allChess[i].getPosX() + "-" + allChess[i].getPosY());
// ? ? ? ?}
// ? ?}
? ? // 翻轉(zhuǎn)棋盤
? ? private void reverseMap() {
? ? ? ? int t;
? ? ? ? // 默認(rèn)為黑下紅上
? ? ? ? // 主機(jī)為黑下紅上
? ? ? ? // 客戶端為黑上紅下,所以是客戶端時將雙方棋的位置換一下
? ? ? ? for (int i = 0; i < ROW / 2; i++) {
? ? ? ? ? ? for (int j = 0; j < COL; j++) {
? ? ? ? ? ? ? ? t = map[i][j];
? ? ? ? ? ? ? ? map[i][j] = map[ROW - i - 1][j];
? ? ? ? ? ? ? ? map[ROW - i - 1][j] = t;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? for (Chess c : allChess) {
? ? ? ? ? ? c.reverse();
? ? ? ? }
// ? ? ? ?showChess();
? ? }

? ? public void startServer() {
? ? ? ? // 將主活動的輔助控件隱藏掉
? ? ? ? context.uiGone();
? ? ? ? tvTip.setText("等待連接...");
? ? ? ? // 開啟接收信息的線程
? ? ? ? new MessageThread().start();
? ? }

? ? public void sendMes(final String s) {
? ? ? ? // 發(fā)送信息,要在線程里執(zhí)行(異步執(zhí)行)
? ? ? ? new Thread(new Runnable() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void run() {
? ? ? ? ? ? ? ? DatagramSocket ds = null;
? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? ? ds = new DatagramSocket();
? ? ? ? ? ? ? ? ? ? byte[] buffer;
? ? ? ? ? ? ? ? ? ? buffer = s.getBytes();
? ? ? ? ? ? ? ? ? ? InetAddress ia = InetAddress.getByName(ip);
? ? ? ? ? ? ? ? ? ? DatagramPacket dp = new DatagramPacket(buffer, buffer.length, ia, sendPort);
? ? ? ? ? ? ? ? ? ? ds.send(dp);
? ? ? ? ? ? ? ? } catch (IOException e) {
? ? ? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? ? ? } finally {
? ? ? ? ? ? ? ? ? ? if (ds != null) {
? ? ? ? ? ? ? ? ? ? ? ? ds.close();
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }).start();
? ? }
? ? // 每次調(diào)用 invalidate 就會執(zhí)行這個方法
? ? @Override
? ? protected void onDraw(Canvas canvas) {
? ? ? ? // 畫筆,用于設(shè)置線條樣式
? ? ? ? Paint paint = new Paint();
? ? ? ? paint.setStrokeWidth(5);
? ? ? ? paint.setStyle(Paint.Style.STROKE);
? ? ? ? // 設(shè)置棋盤圖片,寬高視手機(jī)分辨率而定
? ? ? ? canvas.drawBitmap(getBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.bg), 1080, 1195), 0, MARGINTOP, paint);
? ? ? ? // 畫棋
? ? ? ? for (Chess allChes : allChess) {
? ? ? ? ? ? // 若沒有被吃掉
? ? ? ? ? ? if (allChes != null) {
? ? ? ? ? ? ? ? // x 坐標(biāo)為列坐標(biāo)乘以格子的寬度然后減去一半的格子寬度,讓棋子的中心對齊坐標(biāo)頂點(diǎn)
? ? ? ? ? ? ? ? int x = allChes.getPosY() * W + MARGINLEFT - W / 2;
? ? ? ? ? ? ? ? int y = allChes.getPosX() * W + MARGINTOP + MARGINLEFT - W / 2;
? ? ? ? ? ? ? ? canvas.drawBitmap(getBitmap(BitmapFactory.decodeResource(getResources(), allChes.getImageId()), W, W), x, y, paint);
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? // 若第一次選擇了則畫一個矩陣邊框來顯示已選中
? ? ? ? if (firstSelect != null) {
? ? ? ? ? ? paint.setColor(Color.RED);
? ? ? ? ? ? int x = firstSelect.getPosY() * W + MARGINLEFT - W / 2;
? ? ? ? ? ? int y = firstSelect.getPosX() * W + MARGINTOP + MARGINLEFT - W / 2;
? ? ? ? ? ? // 畫線
? ? ? ? ? ? int[] posX = {x, x + W, x + W, x, x};
? ? ? ? ? ? int[] posY = {y, y, y + W, y + W, y};
? ? ? ? ? ? Path path = new Path();
? ? ? ? ? ? path.moveTo(posX[0], posY[0]);
? ? ? ? ? ? for (int i = 1; i < posX.length; i++) {
? ? ? ? ? ? ? ? path.lineTo(posX[i], posY[i]);
? ? ? ? ? ? }
? ? ? ? ? ? canvas.drawPath(path, paint);
? ? ? ? }
? ? }
? ? // 自定義圖片寬高
? ? private Bitmap getBitmap(Bitmap rootImg, int w, int h) {
? ? ? ? int rW = rootImg.getWidth();
? ? ? ? int rH = rootImg.getHeight();
? ? ? ? Matrix matrix = new Matrix();
? ? ? ? matrix.postScale(w * 1.0f / rW, h * 1.0f / rH);
? ? ? ? return Bitmap.createBitmap(rootImg, 0, 0, rW, rH, matrix, true);
? ? }
? ? // 重新開始游戲
? ? private void restartGame() {
? ? ? ? // 重新初始化棋盤
? ? ? ? initMapAndChess();
? ? ? ? // 若是黑棋則先下
? ? ? ? canPlay = true;
? ? ? ? String tip = "已重新開始游戲,我下";
? ? ? ? if (player == RED) {
? ? ? ? ? ? reverseMap();
? ? ? ? ? ? canPlay = false;
? ? ? ? ? ? tip = "已重新開始游戲,對方下";
? ? ? ? }
? ? ? ? isWin = false;
? ? ? ? // 給提示,在線程中更新 UI 時需轉(zhuǎn)到主線程上
? ? ? ? setTip(tip);
? ? ? ? // 刷新視圖
? ? ? ? updateOnUI();
? ? }
? ? // 接受信息的線程
? ? class MessageThread extends Thread {
? ? ? ? @Override
? ? ? ? public void run() {
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? DatagramSocket ds = new DatagramSocket(receiverPort);
? ? ? ? ? ? ? ? byte[] buffer = new byte[100];
? ? ? ? ? ? ? ? DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
? ? ? ? ? ? ? ? // 發(fā)送加入信息
? ? ? ? ? ? ? ? sendMes("join|");
? ? ? ? ? ? ? ? while (true) {
? ? ? ? ? ? ? ? ? ? ds.receive(dp);
? ? ? ? ? ? ? ? ? ? String s = new String(buffer);
? ? ? ? ? ? ? ? ? ? // 指定分割符分割信息
? ? ? ? ? ? ? ? ? ? String[] array = s.split("\\|");
? ? ? ? ? ? ? ? ? ? switch (array[0]) {
? ? ? ? ? ? ? ? ? ? ? ? // 只有主機(jī)才會接收到
? ? ? ? ? ? ? ? ? ? ? ? case "join":
? ? ? ? ? ? ? ? ? ? ? ? ? ? player = BLACK;
? ? ? ? ? ? ? ? ? ? ? ? ? ? canPlay = true;
? ? ? ? ? ? ? ? ? ? ? ? ? ? sendMes("conn|");
? ? ? ? ? ? ? ? ? ? ? ? ? ? setTip("我是黑棋,我下");
? ? ? ? ? ? ? ? ? ? ? ? ? ? context.runOnUiThread(new Runnable() {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @Override
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? public void run() {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? btnNewGame.setEnabled(true);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? });
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? // 只有客戶端才會接收到
? ? ? ? ? ? ? ? ? ? ? ? case "conn":
? ? ? ? ? ? ? ? ? ? ? ? ? ? player = RED;
? ? ? ? ? ? ? ? ? ? ? ? ? ? // 要翻轉(zhuǎn)棋盤
? ? ? ? ? ? ? ? ? ? ? ? ? ? reverseMap();
? ? ? ? ? ? ? ? ? ? ? ? ? ? updateOnUI();
? ? ? ? ? ? ? ? ? ? ? ? ? ? canPlay = false;
? ? ? ? ? ? ? ? ? ? ? ? ? ? setTip("我是紅棋,對方下");
? ? ? ? ? ? ? ? ? ? ? ? ? ? context.runOnUiThread(new Runnable() {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @Override
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? public void run() {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? btnNewGame.setEnabled(true);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? });
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? // 接受到了移動信息
? ? ? ? ? ? ? ? ? ? ? ? case "move":
? ? ? ? ? ? ? ? ? ? ? ? ? ? // 判斷是否贏了,若贏了則后面的不執(zhí)行
? ? ? ? ? ? ? ? ? ? ? ? ? ? if (isWin) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? continue;
? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? // 對方走的棋編號
? ? ? ? ? ? ? ? ? ? ? ? ? ? int originalPos = Integer.valueOf(array[1]);
? ? ? ? ? ? ? ? ? ? ? ? ? ? // 要走的行坐標(biāo)
? ? ? ? ? ? ? ? ? ? ? ? ? ? int y2 = ROW - Integer.valueOf(array[2]) - 1;
? ? ? ? ? ? ? ? ? ? ? ? ? ? // 要走的列坐標(biāo)
? ? ? ? ? ? ? ? ? ? ? ? ? ? int x2 = Integer.valueOf(array[3]);
? ? ? ? ? ? ? ? ? ? ? ? ? ? // 我方當(dāng)前的對方要走的棋行列坐標(biāo)
? ? ? ? ? ? ? ? ? ? ? ? ? ? int y1 = allChess[originalPos].getPosX();
? ? ? ? ? ? ? ? ? ? ? ? ? ? int x1 = allChess[originalPos].getPosY();
? ? ? ? ? ? ? ? ? ? ? ? ? ? // 存儲要走向的坐標(biāo)在棋盤的編號
? ? ? ? ? ? ? ? ? ? ? ? ? ? int movePos = map[y2][x2];
? ? ? ? ? ? ? ? ? ? ? ? ? ? // 將原來的位置置空
? ? ? ? ? ? ? ? ? ? ? ? ? ? map[y1][x1] = NULL;
? ? ? ? ? ? ? ? ? ? ? ? ? ? // 要走的位置設(shè)置為對方的棋編號
? ? ? ? ? ? ? ? ? ? ? ? ? ? map[y2][x2] = originalPos;
? ? ? ? ? ? ? ? ? ? ? ? ? ? // 更新其坐標(biāo)
? ? ? ? ? ? ? ? ? ? ? ? ? ? allChess[originalPos].setPos(y2, x2);
? ? ? ? ? ? ? ? ? ? ? ? ? ? // 判斷要走的位置是否有棋,若有,則置空
? ? ? ? ? ? ? ? ? ? ? ? ? ? if (movePos != NULL && allChess[movePos] != null) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? allChess[movePos] = null;
? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? // 更新視圖
? ? ? ? ? ? ? ? ? ? ? ? ? ? updateOnUI();
? ? ? ? ? ? ? ? ? ? ? ? ? ? // 我方可以下棋
? ? ? ? ? ? ? ? ? ? ? ? ? ? canPlay = true;
? ? ? ? ? ? ? ? ? ? ? ? ? ? setTip("我下");
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? // 對方贏了
? ? ? ? ? ? ? ? ? ? ? ? case "winner":
? ? ? ? ? ? ? ? ? ? ? ? ? ? isWin = true;
? ? ? ? ? ? ? ? ? ? ? ? ? ? whoWin();
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? // 重新開始游戲
? ? ? ? ? ? ? ? ? ? ? ? case "restart":
? ? ? ? ? ? ? ? ? ? ? ? ? ? restartGame();
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? } catch (IOException e) {
? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? }
? ? ? ? }
? ? }
?? ?// 有贏家后
? ? private void whoWin() {
? ? ? ? canPlay = false;
? ? ? ? setTip("對方獲勝");
? ? }
?? ?// 更新視圖
? ? private void updateOnUI() {
? ? ? ? context.runOnUiThread(new Runnable() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void run() {
? ? ? ? ? ? ? ? invalidate();
? ? ? ? ? ? }
? ? ? ? });
? ? }
?? ?// 設(shè)置提示信息
? ? private void setTip(final String s) {
? ? ? ? context.runOnUiThread(new Runnable() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void run() {
? ? ? ? ? ? ? ? tvTip.setText(s);
? ? ? ? ? ? }
? ? ? ? });
? ? }
}

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論