Android實(shí)現(xiàn)五子棋游戲(局域網(wǎng)版)
本文實(shí)例為大家分享了Android實(shí)現(xiàn)五子棋游戲的具體代碼,供大家參考,具體內(nèi)容如下
實(shí)現(xiàn)環(huán)境: android studio 3.2.1, 手機(jī)分辨率為: 1920 * 1080
局域網(wǎng)采用 Socket 連接
分主活動(dòng)類,主機(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" />
主活動(dòng):
package fivechess; import android.os.Bundle; import android.preference.PreferenceManager; import android.support.v7.app.AppCompatActivity; 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 { ? ? private TextView txtMain; ? ? private Button serverBtn; ? ? private TextView txtClient; ? ? private EditText ipText; ? ? private Button clientBtn; ? ? private int ip = 10000; ? ? @Override ? ? protected void onCreate(Bundle savedInstanceState) { ? ? ? ? super.onCreate(savedInstanceState); ? ? ? ? setContentView(R.layout.activity_main); ? ? ? ? initView(); ? ? } ? ? private void initView() { ? ? ? ? txtMain = (TextView) findViewById(R.id.txtMain); ? ? ? ? serverBtn = (Button) findViewById(R.id.serverBtn); ? ? ? ? txtClient = (TextView) findViewById(R.id.txtClient); ? ? ? ? ipText = (EditText) findViewById(R.id.ipText); ? ? ? ? clientBtn = (Button) findViewById(R.id.clientBtn); ? ? ? ? ipText.setText(getPreference("myIp")); ? ? ? ? // 顯示本機(jī)的 ip 地址 ? ? ? ? setIp(); ? ? ? ? // 根據(jù)按鈕來判斷作為主機(jī)還是客戶端 ? ? ? ? final ViewGroup.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); ? ? ? ? serverBtn.setOnClickListener(new View.OnClickListener() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public void onClick(View v) { ? ? ? ? ? ? ? ? ServerView serverView = new ServerView(MainActivity.this, ip, MainActivity.this); ? ? ? ? ? ? ? ? addContentView(serverView, params); ? ? ? ? ? ? ? ? serverView.startConn(); ? ? ? ? ? ? ? ? // 將當(dāng)前控件隱藏掉 ? ? ? ? ? ? ? ? viewGone(); ? ? ? ? ? ? } ? ? ? ? }); ? ? ? ? clientBtn.setOnClickListener(new View.OnClickListener() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public void onClick(View v) { ? ? ? ? ? ? ? ? if (ipText.getText().toString().isEmpty()) { ? ? ? ? ? ? ? ? ? ? Toast.makeText(MainActivity.this, "IP 不能為空!", Toast.LENGTH_SHORT).show(); ? ? ? ? ? ? ? ? ? ? return; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ClientView clientView = new ClientView(MainActivity.this, ipText.getText().toString(), ip, MainActivity.this); ? ? ? ? ? ? ? ? addContentView(clientView, params); ? ? ? ? ? ? ? ? clientView.startJoin(); ? ? ? ? ? ? ? ? // 將當(dāng)前控件隱藏掉 ? ? ? ? ? ? ? ? viewGone(); ? ? ? ? ? ? } ? ? ? ? }); ? ? } ? ? // 存儲(chǔ)當(dāng)前輸入的 ip ? ? public void setMyIp() { ? ? ? ? setPreference("myIp", ipText.getText().toString()); ? ? } ? ? // 用于獲取本機(jī) ip 地址 ? ? public void setIp() { ? ? ? ? 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(); ? ? ? ? ? ? ? ? ? ? ? ? // 只獲取局域網(wǎng)地址 ? ? ? ? ? ? ? ? ? ? ? ? if ("192".equals(s.substring(0, 3))) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? txtMain.setText(txtMain.getText().toString() + " ?主機(jī)ip: " + s); ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? } catch (SocketException e) { ? ? ? ? ? ? e.printStackTrace(); ? ? ? ? } ? ? } ? ? // 隱藏主活動(dòng)的輔助空間 ? ? public void viewGone() { ? ? ? ? txtMain.setVisibility(View.GONE); ? ? ? ? serverBtn.setVisibility(View.GONE); ? ? ? ? txtClient.setVisibility(View.GONE); ? ? ? ? ipText.setVisibility(View.GONE); ? ? ? ? clientBtn.setVisibility(View.GONE); ? ? } ? ? // 用于獲取上次的ip輸入地址 ? ? public String getPreference(String key) { ? ? ? ? return PreferenceManager.getDefaultSharedPreferences(this).getString(key, "192.168."); ? ? } ? ? // 用于存儲(chǔ)數(shù)據(jù)到本地 ? ? public void setPreference(String key, String value) { ? ? ? ? PreferenceManager.getDefaultSharedPreferences(this).edit().putString(key, value).apply(); ? ? } }
布局:
效果圖
代碼:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" ? ? xmlns:tools="http://schemas.android.com/tools" ? ? android:layout_width="match_parent" ? ? android:layout_height="match_parent" ? ? android:orientation="vertical" ? ? tools:context=".MainActivity"> ? ? <TextView ? ? ? ? android:id="@+id/txtMain" ? ? ? ? android:layout_width="match_parent" ? ? ? ? android:layout_height="wrap_content" ? ? ? ? android:layout_margin="10dp" ? ? ? ? android:text="作為主機(jī)" ? ? ? ? android:textColor="#000" /> ? ? <Button ? ? ? ? android:id="@+id/serverBtn" ? ? ? ? android:layout_width="match_parent" ? ? ? ? android:layout_height="wrap_content" ? ? ? ? android:text="start server" /> ? ? <TextView ? ? ? ? android:id="@+id/txtClient" ? ? ? ? android:layout_width="match_parent" ? ? ? ? android:layout_height="wrap_content" ? ? ? ? android:layout_margin="10dp" ? ? ? ? android:text="作為客戶端" ? ? ? ? android:textColor="#000" /> ? ? <EditText ? ? ? ? android:id="@+id/ipText" ? ? ? ? android:layout_width="match_parent" ? ? ? ? android:layout_height="wrap_content" ? ? ? ? android:hint="ip" ? ? ? ? android:text="192.168.31.163" /> ? ? <Button ? ? ? ? android:id="@+id/clientBtn" ? ? ? ? android:layout_width="match_parent" ? ? ? ? android:layout_height="wrap_content" ? ? ? ? android:text="client connection" /> </LinearLayout>
主機(jī)類:
package fivechess; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; 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 android.widget.Toast; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.List; import java.util.Timer; import java.util.TimerTask; public class ServerView extends View { ? ? // 上邊距 ? ? public static final int TOP = 200; ? ? // 棋盤的左,上邊距 ? ? public static final int MARGINLEFT = 50, MARGINTOP = 100 + TOP; ? ? // 棋子的寬度,視情況而定 ? ? public static final int CHESSW = 62; ? ? // 格子的寬度,視情況而定 ? ? public static final int W = 70; ? ? // 14個(gè)格子,15條行列坐標(biāo) ? ? public static final int L = 15; ? ? public static final int BLOCKL = 14; ? ? // 棋的顏色標(biāo)記 ? ? public static final int BLACK = 2, WHITE = 1; // ? ?public static final int NULL = -1; ? ? // 棋盤的寬度 ? ? private int width = W * BLOCKL; ? ? // 棋盤的高度 ? ? private int height = W * BLOCKL; ? ? // 標(biāo)記我方的棋的顏色 ? ? private int player; ? ? // 存儲(chǔ)所有走過的棋的信息,主要為坐標(biāo) ? ? private List<String> allList = new ArrayList<>(); ? ? // 存儲(chǔ)我方走過的棋的信息 ? ? private List<String> myList = new ArrayList<>(); ? ? // 存儲(chǔ)對方走過的棋的信息 ? ? private List<String> enemyList = new ArrayList<>(); ? ? // 是否可以走棋 ? ? private boolean canPlay; ? ? // 是否有滑動(dòng)事件 ? ? private boolean isMove; ? ? // 用于開啟服務(wù)器,所有的網(wǎng)絡(luò)請求都要在線程中執(zhí)行 ? ? private ServerSocket serverSocket; ? ? // 用于與客戶端交互 ? ? private Socket socket; ? ? // 對方端口 ? ? private int port; ? ? // 用于發(fā)送消息 ? ? private PrintWriter pw; ? ? // 主活動(dòng) ? ? private MainActivity mainActivity; ? ? // 提示文本框 ? ? private TextView tvTip; ? ? // 重新開始 ? ? private Button btnRestart; ? ? public ServerView(Context context, int port, MainActivity mainActivity) { ? ? ? ? super(context); ? ? ? ? this.port = port; ? ? ? ? this.mainActivity = mainActivity; ? ? ? ? // 初始化棋盤 ? ? ? ? initMap(); ? ? ? ? // 添加提示文本框控件和重新開始按鈕 ? ? ? ? ViewGroup.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); ? ? ? ? tvTip = new TextView(context); ? ? ? ? tvTip.setText("等待連接..."); ? ? ? ? tvTip.setX(500); ? ? ? ? tvTip.setY(20); ? ? ? ? mainActivity.addContentView(tvTip, params); ? ? ? ? btnRestart = new Button(context); ? ? ? ? btnRestart.setText("重新開始"); ? ? ? ? btnRestart.setX(MARGINLEFT); ? ? ? ? btnRestart.setY(20); ? ? ? ? mainActivity.addContentView(btnRestart, params); ? ? ? ? btnRestart.setEnabled(false); ? ? ? ? btnRestart.setOnClickListener(new OnClickListener() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public void onClick(View v) { ? ? ? ? ? ? ? ? // 重新開始游戲 ? ? ? ? ? ? ? ? restartGame(); ? ? ? ? ? ? ? ? // 發(fā)送消息給客戶端 ? ? ? ? ? ? ? ? sendMes("restart"); ? ? ? ? ? ? } ? ? ? ? }); ? ? ? ? setOnTouchListener(new OnTouchListener() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public boolean onTouch(View v, MotionEvent event) { ? ? ? ? ? ? ? ? switch (event.getAction()) { ? ? ? ? ? ? ? ? ? ? case MotionEvent.ACTION_DOWN: ? ? ? ? ? ? ? ? ? ? ? ? isMove = false; ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? ? ? ? ? // 判斷是否為滑動(dòng)事件 ? ? ? ? ? ? ? ? ? ? case MotionEvent.ACTION_MOVE: ? ? ? ? ? ? ? ? ? ? ? ? isMove = true; ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? ? ? case MotionEvent.ACTION_UP: ? ? ? ? ? ? ? ? ? ? ? ? if (!canPlay) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? // 只可處理點(diǎn)擊事件 ? ? ? ? ? ? ? ? ? ? ? ? if (!isMove) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 獲取當(dāng)前點(diǎn)擊位置的 x, y 坐標(biāo) ? ? ? ? ? ? ? ? ? ? ? ? ? ? int x = (int) event.getX() - MARGINLEFT; ? ? ? ? ? ? ? ? ? ? ? ? ? ? int y = (int) event.getY() - MARGINTOP; ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 是否在棋盤外 ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (x < -W / 2 || x > width + W / 2 || y < -W / 2 || y > width + W / 2) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 轉(zhuǎn)化為棋盤的 col 列坐標(biāo) ? ? ? ? ? ? ? ? ? ? ? ? ? ? // x % W > W / 2 ? 1 : 0 為當(dāng)前的位置的求模后是否滿足大于一半的寬度, ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 若大于則把它安排到下一個(gè)位置,否則不變 ? ? ? ? ? ? ? ? ? ? ? ? ? ? x = x / W + (x % W > W / 2 ? 1 : 0); ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 轉(zhuǎn)化為棋盤的 row 行坐標(biāo) ? ? ? ? ? ? ? ? ? ? ? ? ? ? y = y / W + (y % W > W / 2 ? 1 : 0); ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 設(shè)置移動(dòng)信息 ? ? ? ? ? ? ? ? ? ? ? ? ? ? String move = y + "|" + x; ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 當(dāng)前位置是否有棋存在 ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (allList.contains(move)) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 把當(dāng)前移動(dòng)位置添加到所有列表中 ? ? ? ? ? ? ? ? ? ? ? ? ? ? allList.add(move); ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 把當(dāng)前移動(dòng)位置添加到我方列表中 ? ? ? ? ? ? ? ? ? ? ? ? ? ? myList.add(move); ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 將移動(dòng)消息發(fā)送給對面 ? ? ? ? ? ? ? ? ? ? ? ? ? ? sendMes("move|" + move); ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 輪到對方下 ? ? ? ? ? ? ? ? ? ? ? ? ? ? canPlay = false; ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 設(shè)置提示信息 ? ? ? ? ? ? ? ? ? ? ? ? ? ? tvTip.setText("對方下"); ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 更新視圖 ? ? ? ? ? ? ? ? ? ? ? ? ? ? invalidate(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 判斷是否贏了 ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (isWin()) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Toast.makeText(getContext(), "黑棋獲勝!", Toast.LENGTH_SHORT).show(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? tvTip.setText("我方獲勝!"); ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? return true; ? ? ? ? ? ? } ? ? ? ? }); ? ? } ? ? // 開啟服務(wù)器 ? ? public void startConn() { ? ? ? ? // 只能在線程(異步)中執(zhí)行 ? ? ? ? new Timer().schedule(new TimerTask() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public void run() { ? ? ? ? ? ? ? ? try { ? ? ? ? ? ? ? ? ? ? serverSocket = new ServerSocket(port); ? ? ? ? ? ? ? ? ? ? // 獲取客戶端信息,若無客戶端連接則會(huì)一直暫停在這 ? ? ? ? ? ? ? ? ? ? socket = serverSocket.accept(); ? ? ? ? ? ? ? ? ? ? setTip("連接成功!"); ? ? ? ? ? ? ? ? ? ? // 發(fā)送已連接給客戶端 ? ? ? ? ? ? ? ? ? ? sendMes("conn|"); ? ? ? ? ? ? ? ? ? ? // 開啟接受消息的線程 ? ? ? ? ? ? ? ? ? ? new MyThread().start(); ? ? ? ? ? ? ? ? ? ? // 更新視圖 ? ? ? ? ? ? ? ? ? ? invalidate(); ? ? ? ? ? ? ? ? } catch (IOException e) { ? ? ? ? ? ? ? ? ? ? e.printStackTrace(); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? }, 0); ? ? } ? ? // 是否贏了 ? ? private boolean isWin() { ? ? ? ? // 好像有點(diǎn)多此一舉... ? ? ? ? return isCanLink(); ? ? } ? ? // 是否有了輸贏 ? ? private boolean isCanLink() { ? ? ? ? // 黑棋先,服務(wù)端為黑棋,客戶端為白棋 ? ? ? ? // 判斷最后下的是誰,為0為白棋,為1為黑棋 ? ? ? ? int who = allList.size() % 2; ? ? ? ? // 將行列坐標(biāo)分割出來 ? ? ? ? String[] t = allList.get(allList.size() - 1).split("\\|"); ? ? ? ? // 行坐標(biāo) ? ? ? ? int r1 = Integer.valueOf(t[0]); ? ? ? ? // 列坐標(biāo) ? ? ? ? int c1 = Integer.valueOf(t[1]); ? ? ? ? // 垂直方向是否有五子 ? ? ? ? if (canVLink(who, r1, c1)) { ? ? ? ? ? ? return true; ? ? ? ? } ? ? ? ? // 水平方向是否有五子 ? ? ? ? if (canHLink(who, r1, c1)) { ? ? ? ? ? ? return true; ? ? ? ? } ? ? ? ? // 左下右上方向 ? ? ? ? if (canLeftObliqueLink(who, r1, c1)) { ? ? ? ? ? ? return true; ? ? ? ? } ? ? ? ? // 左上右下方向 ? ? ? ? if (canRightObliqueLink(who, r1, c1)) { ? ? ? ? ? ? return true; ? ? ? ? } ? ? ? ? return false; ? ? } ? ? // 左上右下方向 ? ? private boolean canRightObliqueLink(int who, int r1, int c1) { ? ? ? ? // 記錄連子的個(gè)數(shù) ? ? ? ? int count = 0; ? ? ? ? // 遍歷要用到的行列坐標(biāo) ? ? ? ? int r2; ? ? ? ? int c2; ? ? ? ? // 黑棋 ? ? ? ? if (who == 1) { ? ? ? ? ? ? // left top ? ? ? ? ? ? r2 = r1 - 1; ? ? ? ? ? ? c2 = c1 - 1; ? ? ? ? ? ? // 往左上方向遍歷,若存在則表示有連棋 ? ? ? ? ? ? while (myList.contains(r2 + "|" + c2)) { ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? r2--; ? ? ? ? ? ? ? ? c2--; ? ? ? ? ? ? } ? ? ? ? ? ? // right down ? ? ? ? ? ? r2 = r1 + 1; ? ? ? ? ? ? c2 = c1 + 1; ? ? ? ? ? ? // 往右下方向遍歷 ? ? ? ? ? ? while (myList.contains(r2 + "|" + c2)) { ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? r2++; ? ? ? ? ? ? ? ? c2++; ? ? ? ? ? ? } ? ? ? ? ? ? // 若有四個(gè)以上則代表構(gòu)成五子 ? ? ? ? ? ? if (count >= 4) { ? ? ? ? ? ? ? ? return true; ? ? ? ? ? ? } ? ? ? ? } else { ? ? ? ? ? ? // 紅棋 ? ? ? ? ? ? // right top ? ? ? ? ? ? r2 = r1 - 1; ? ? ? ? ? ? c2 = c1 - 1; ? ? ? ? ? ? // 往左上方向遍歷 ? ? ? ? ? ? while (enemyList.contains(r2 + "|" + c2)) { ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? r2--; ? ? ? ? ? ? ? ? c2--; ? ? ? ? ? ? } ? ? ? ? ? ? // left down ? ? ? ? ? ? r2 = r1 + 1; ? ? ? ? ? ? c2 = c1 + 1; ? ? ? ? ? ? // 往右下方向遍歷 ? ? ? ? ? ? while (enemyList.contains(r2 + "|" + c2)) { ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? r2++; ? ? ? ? ? ? ? ? c2++; ? ? ? ? ? ? } ? ? ? ? ? ? // 若有四個(gè)以上則代表構(gòu)成五子 ? ? ? ? ? ? if (count >= 4) { ? ? ? ? ? ? ? ? return true; ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? return false; ? ? } ? ? // 左下右上方向 ? ? private boolean canLeftObliqueLink(int who, int r1, int c1) { ? ? ? ? int count = 0; ? ? ? ? int r2; ? ? ? ? int c2; ? ? ? ? // 黑棋 ? ? ? ? if (who == 1) { ? ? ? ? ? ? // right top ? ? ? ? ? ? r2 = r1 - 1; ? ? ? ? ? ? c2 = c1 + 1; ? ? ? ? ? ? while (myList.contains(r2 + "|" + c2)) { ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? r2--; ? ? ? ? ? ? ? ? c2++; ? ? ? ? ? ? } ? ? ? ? ? ? // left down ? ? ? ? ? ? r2 = r1 + 1; ? ? ? ? ? ? c2 = c1 - 1; ? ? ? ? ? ? while (myList.contains(r2 + "|" + c2)) { ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? r2++; ? ? ? ? ? ? ? ? c2--; ? ? ? ? ? ? } ? ? ? ? ? ? if (count >= 4) { ? ? ? ? ? ? ? ? return true; ? ? ? ? ? ? } ? ? ? ? } else { ? ? ? ? ? ? // 白棋 ? ? ? ? ? ? // right top ? ? ? ? ? ? r2 = r1 - 1; ? ? ? ? ? ? c2 = c1 + 1; ? ? ? ? ? ? while (enemyList.contains(r2 + "|" + c2)) { ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? r2--; ? ? ? ? ? ? ? ? c2++; ? ? ? ? ? ? } ? ? ? ? ? ? // left down ? ? ? ? ? ? r2 = r1 + 1; ? ? ? ? ? ? c2 = c1 - 1; ? ? ? ? ? ? while (enemyList.contains(r2 + "|" + c2)) { ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? r2++; ? ? ? ? ? ? ? ? c2--; ? ? ? ? ? ? } ? ? ? ? ? ? if (count >= 4) { ? ? ? ? ? ? ? ? return true; ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? return false; ? ? } ? ? // 水平方向 ? ? private boolean canHLink(int who, int r1, int c1) { ? ? ? ? int count = 0; ? ? ? ? int c2; ? ? ? ? // 黑棋 ? ? ? ? if (who == 1) { ? ? ? ? ? ? // left ? ? ? ? ? ? c2 = c1 - 1; ? ? ? ? ? ? while (myList.contains(r1 + "|" + c2)) { ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? c2--; ? ? ? ? ? ? } ? ? ? ? ? ? // right ? ? ? ? ? ? c2 = c1 + 1; ? ? ? ? ? ? while (myList.contains(r1 + "|" + c2)) { ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? c2++; ? ? ? ? ? ? } ? ? ? ? ? ? if (count >= 4) { ? ? ? ? ? ? ? ? return true; ? ? ? ? ? ? } ? ? ? ? } else { ? ? ? ? ? ? // 白棋 ? ? ? ? ? ? // left ? ? ? ? ? ? c2 = c1 - 1; ? ? ? ? ? ? while (enemyList.contains(r1 + "|" + c2)) { ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? c2--; ? ? ? ? ? ? } ? ? ? ? ? ? // right ? ? ? ? ? ? c2 = c1 + 1; ? ? ? ? ? ? while (enemyList.contains(r1 + "|" + c2)) { ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? c2++; ? ? ? ? ? ? } ? ? ? ? ? ? if (count >= 4) { ? ? ? ? ? ? ? ? return true; ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? return false; ? ? } ? ? // 垂直方向 ? ? private boolean canVLink(int who, int r1, int c1) { ? ? ? ? int count = 0; ? ? ? ? int r2; ? ? ? ? // 黑棋 ? ? ? ? if (who == 1) { ? ? ? ? ? ? // top ? ? ? ? ? ? r2 = r1 - 1; ? ? ? ? ? ? while (myList.contains(r2 + "|" + c1)) { ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? r2--; ? ? ? ? ? ? } ? ? ? ? ? ? // down ? ? ? ? ? ? r2 = r1 + 1; ? ? ? ? ? ? while (myList.contains(r2 + "|" + c1)) { ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? r2++; ? ? ? ? ? ? } ? ? ? ? ? ? if (count >= 4) { ? ? ? ? ? ? ? ? return true; ? ? ? ? ? ? } ? ? ? ? } else { ? ? ? ? ? ? // 白棋 ? ? ? ? ? ? // top ? ? ? ? ? ? r2 = r1 - 1; ? ? ? ? ? ? while (enemyList.contains(r2 + "|" + c1)) { ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? r2--; ? ? ? ? ? ? } ? ? ? ? ? ? // down ? ? ? ? ? ? r2 = r1 + 1; ? ? ? ? ? ? while (enemyList.contains(r2 + "|" + c1)) { ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? r2++; ? ? ? ? ? ? } ? ? ? ? ? ? if (count >= 4) { ? ? ? ? ? ? ? ? return true; ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? return false; ? ? } ? ? // 接受消息的線程 ? ? class MyThread extends Thread { ? ? ? ? @Override ? ? ? ? public void run() { ? ? ? ? ? ? BufferedReader br = null; ? ? ? ? ? ? InputStreamReader isr = null; ? ? ? ? ? ? try { ? ? ? ? ? ? ? ? String t; ? ? ? ? ? ? ? ? while (true) { ? ? ? ? ? ? ? ? ? ? // 睡眠一段時(shí)間,不必每毫秒都執(zhí)行 ? ? ? ? ? ? ? ? ? ? sleep(100); ? ? ? ? ? ? ? ? ? ? isr = new InputStreamReader(socket.getInputStream()); ? ? ? ? ? ? ? ? ? ? br = new BufferedReader(isr); ? ? ? ? ? ? ? ? ? ? // 是否接受到了消息 ? ? ? ? ? ? ? ? ? ? if (br.ready()) { ? ? ? ? ? ? ? ? ? ? ? ? String cmd = br.readLine(); ? ? ? ? ? ? ? ? ? ? ? ? // 分割信息 ? ? ? ? ? ? ? ? ? ? ? ? String[] array = cmd.split("\\|"); ? ? ? ? ? ? ? ? ? ? ? ? switch (array[0]) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 一定是服務(wù)器接受到這個(gè)消息 ? ? ? ? ? ? ? ? ? ? ? ? ? ? case "join": ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 服務(wù)器一定為黑棋 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? player = BLACK; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 我方先下 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? canPlay = true; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 發(fā)送消息給客戶端 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sendMes("conn|"); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? setTip("我下"); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // UI 更新一定在主線程中執(zhí)行 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 重新開始按鈕可以點(diǎn)了,這個(gè)方法可以賺到主線程中 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? post(new Runnable() { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @Override ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? public void run() { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? btnRestart.setEnabled(true); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mainActivity.runOnUiThread(new Runnable() { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @Override ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? public void run() { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Toast.makeText(mainActivity, "你是黑棋", Toast.LENGTH_SHORT).show(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? ? ? ? ? ? ? case "move": ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 存儲(chǔ)對方走的棋坐標(biāo) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? t = array[1] + "|" + array[2]; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? allList.add(t); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? enemyList.add(t); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 我方走棋 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? canPlay = true; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? setTip("我下"); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 是否有了輸贏 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (isWin()) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? post(new Runnable() { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @Override ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? public void run() { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Toast.makeText(getContext(), "白棋獲勝!", Toast.LENGTH_SHORT).show(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? tvTip.setText("對方獲勝!"); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? canPlay = false; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? invalidate(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? ? ? ? ? ? ? case "restart": ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 重新開始游戲 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? restartGame(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } catch (IOException e) { ? ? ? ? ? ? ? ? e.printStackTrace(); ? ? ? ? ? ? } catch (InterruptedException e) { ? ? ? ? ? ? ? ? e.printStackTrace(); ? ? ? ? ? ? } ? ? ? ? } ? ? } ? ? private void setTip(final String s) { ? ? ? ? post(new Runnable() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public void run() { ? ? ? ? ? ? ? ? tvTip.setText(s); ? ? ? ? ? ? } ? ? ? ? }); ? ? } ? ? // 發(fā)送消息個(gè)客戶端 ? ? private void sendMes(final String s) { ? ? ? ? new Thread(new Runnable() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public void run() { ? ? ? ? ? ? ? ? try { ? ? ? ? ? ? ? ? ? ? pw = new PrintWriter(socket.getOutputStream()); ? ? ? ? ? ? ? ? ? ? pw.println(s); ? ? ? ? ? ? ? ? ? ? pw.flush(); ? ? ? ? ? ? ? ? } catch (IOException e) { ? ? ? ? ? ? ? ? ? ? e.printStackTrace(); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? }).start(); ? ? } ? ? // 初始化棋盤,把列表全部清空 ? ? private void initMap() { ? ? ? ? allList.clear(); ? ? ? ? myList.clear(); ? ? ? ? enemyList.clear(); ? ? } ? ? // 調(diào)用 invalidate 是執(zhí)行 ? ? @Override ? ? protected void onDraw(Canvas canvas) { ? ? ? ? // 畫筆,設(shè)置線條的樣式 ? ? ? ? Paint paint = new Paint(); ? ? ? ? paint.setColor(Color.parseColor("#FFE869")); ? ? ? ? // 設(shè)置棋盤的位置,視情況而定 ? ? ? ? canvas.drawRect(0, TOP, 1080, 1400 + TOP, paint); ? ? ? ? // 設(shè)置畫筆顏色為黑色,用于畫棋盤坐標(biāo)系 ? ? ? ? paint.setColor(Color.BLACK); ? ? ? ? paint.setStrokeWidth(3); ? ? ? ? for (int i = 0; i < L; i++) { ? ? ? ? ? ? int hx = MARGINLEFT; ? ? ? ? ? ? int hy = MARGINTOP + i * W; ? ? ? ? ? ? int vx = MARGINLEFT + i * W; ? ? ? ? ? ? int vy = MARGINTOP; ? ? ? ? ? ? // 畫豎線 ? ? ? ? ? ? canvas.drawLine(hx, hy, MARGINLEFT + width, hy, paint); ? ? ? ? ? ? // 畫橫線 ? ? ? ? ? ? canvas.drawLine(vx, vy, vx, MARGINTOP + height, paint); ? ? ? ? } ? ? ? ? // 畫初始的九個(gè)星位 ? ? ? ? RectF rectF = new RectF(); ? ? ? ? for (int i = 0; i < 3; i++) { ? ? ? ? ? ? for (int j = 0; j < 3; j++) { ? ? ? ? ? ? ? ? int w = 20; ? ? ? ? ? ? ? ? int x = MARGINLEFT + W * 3 + j * W * 4 - w / 2; ? ? ? ? ? ? ? ? int y = MARGINTOP + W * 3 + i * W * 4 - w / 2; ? ? ? ? ? ? ? ? rectF.set(x, y, x + 20, y + 20); ? ? ? ? ? ? ? ? // 畫橢圓 ? ? ? ? ? ? ? ? canvas.drawOval(rectF, paint); ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? // 畫棋子 ? ? ? ? String[] t; ? ? ? ? int r, c; ? ? ? ? for (int i = 0; i < allList.size(); i++) { ? ? ? ? ? ? // 黑棋先,所以黑棋索引為雙數(shù),白棋為單數(shù) ? ? ? ? ? ? if (i % 2 == 0) { ? ? ? ? ? ? ? ? paint.setColor(Color.BLACK); ? ? ? ? ? ? } else { ? ? ? ? ? ? ? ? paint.setColor(Color.WHITE); ? ? ? ? ? ? } ? ? ? ? ? ? t = allList.get(i).split("\\|"); ? ? ? ? ? ? // 行坐標(biāo) ? ? ? ? ? ? r = Integer.valueOf(t[0]); ? ? ? ? ? ? // 列坐標(biāo) ? ? ? ? ? ? c = Integer.valueOf(t[1]); ? ? ? ? ? ? // 使棋子的中心點(diǎn)對其坐標(biāo)頂點(diǎn) ? ? ? ? ? ? c = MARGINLEFT + c * W - CHESSW / 2; ? ? ? ? ? ? r = MARGINTOP + r * W - CHESSW / 2; ? ? ? ? ? ? rectF.set(c, r, c + CHESSW, r + CHESSW); ? ? ? ? ? ? // 畫橢圓 ? ? ? ? ? ? canvas.drawOval(rectF, paint); ? ? ? ? } ? ? } ? ? // 重新開始游戲 ? ? public void restartGame() { ? ? ? ? allList.clear(); ? ? ? ? myList.clear(); ? ? ? ? enemyList.clear(); ? ? ? ? canPlay = true; ? ? ? ? setTip("我下"); ? ? ? ? post(new Runnable() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public void run() { ? ? ? ? ? ? ? ? invalidate(); ? ? ? ? ? ? } ? ? ? ? }); ? ? } }
客戶端類: 與主機(jī)有區(qū)別的地方就是建立連接和接受消息的線程,其它的地方大體相同
代碼如下:
package fivechess; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; 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 android.widget.Toast; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import java.util.ArrayList; import java.util.List; import java.util.Timer; import java.util.TimerTask; public class ClientView extends View { ? ? public static final int TOP = 200; ? ? public static final int MARGINLEFT = 50, MARGINTOP = 100 + TOP; ? ? public static final int W = 70; ? ? public static final int CHESSW = 62; ? ? // 14個(gè)格子,15根線 ? ? public static final int L = 15; ? ? public static final int BLOCKL = 14; ? ? public static final int BLACK = 2, WHITE = 1; ? ? private int width = W * BLOCKL; ? ? private int height = W * BLOCKL; ? ? private int player; ? ? private List<String> allList = new ArrayList<>(); ? ? private List<String> myList = new ArrayList<>(); ? ? private List<String> enemyList = new ArrayList<>(); ? ? private boolean canPlay; ? ? private boolean isMove; ? ? private Socket socket; ? ? private int port; ? ? private String ip; ? ? private MainActivity mainActivity; ? ? private PrintWriter pw; ? ? private TextView tvTip; ? ? private Button btnRestart; ? ? public ClientView(Context context, String ip, int port, MainActivity mainActivity) { ? ? ? ? super(context); ? ? ? ? this.port = port; ? ? ? ? this.ip = ip; ? ? ? ? this.mainActivity = mainActivity; ? ? ? ? initMap(); ? ? ? ? ViewGroup.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); ? ? ? ? tvTip = new TextView(context); ? ? ? ? tvTip.setText("連接中"); ? ? ? ? tvTip.setX(500); ? ? ? ? tvTip.setY(20); ? ? ? ? mainActivity.addContentView(tvTip, params); ? ? ? ? btnRestart = new Button(context); ? ? ? ? btnRestart.setText("重新開始"); ? ? ? ? btnRestart.setX(MARGINLEFT); ? ? ? ? btnRestart.setY(20); ? ? ? ? btnRestart.setEnabled(false); ? ? ? ? mainActivity.addContentView(btnRestart, params); ? ? ? ? btnRestart.setOnClickListener(new OnClickListener() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public void onClick(View v) { ? ? ? ? ? ? ? ? restartGame(); ? ? ? ? ? ? ? ? sendMes("restart"); ? ? ? ? ? ? } ? ? ? ? }); ? ? ? ? setOnTouchListener(new OnTouchListener() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public boolean onTouch(View v, MotionEvent event) { ? ? ? ? ? ? ? ? switch (event.getAction()) { ? ? ? ? ? ? ? ? ? ? case MotionEvent.ACTION_DOWN: ? ? ? ? ? ? ? ? ? ? ? ? isMove = false; ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? ? ? case MotionEvent.ACTION_MOVE: ? ? ? ? ? ? ? ? ? ? ? ? isMove = true; ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? ? ? case MotionEvent.ACTION_UP: ? ? ? ? ? ? ? ? ? ? ? ? if (!canPlay) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? if (!isMove) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? int x = (int) event.getX() - MARGINLEFT; ? ? ? ? ? ? ? ? ? ? ? ? ? ? int y = (int) event.getY() - MARGINTOP; ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (x < -W / 2 || x > width + W / 2 || y < -W / 2 || y > width + W / 2) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? // column ? ? ? ? ? ? ? ? ? ? ? ? ? ? x = x / W + (x % W > W / 2 ? 1 : 0); ? ? ? ? ? ? ? ? ? ? ? ? ? ? // row ? ? ? ? ? ? ? ? ? ? ? ? ? ? y = y / W + (y % W > W / 2 ? 1 : 0); ? ? ? ? ? ? ? ? ? ? ? ? ? ? String move = y + "|" + x; ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (allList.contains(move)) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? allList.add(move); ? ? ? ? ? ? ? ? ? ? ? ? ? ? myList.add(move); ? ? ? ? ? ? ? ? ? ? ? ? ? ? sendMes("move|" + move); ? ? ? ? ? ? ? ? ? ? ? ? ? ? canPlay = false; ? ? ? ? ? ? ? ? ? ? ? ? ? ? tvTip.setText("對方下"); ? ? ? ? ? ? ? ? ? ? ? ? ? ? invalidate(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (isWin()) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Toast.makeText(getContext(), "白棋獲勝!", Toast.LENGTH_SHORT).show(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? tvTip.setText("我方獲勝!"); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sendMes("win"); ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? return true; ? ? ? ? ? ? } ? ? ? ? }); ? ? } ? ? public void startJoin() { ? ? ? ? new Timer().schedule(new TimerTask() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public void run() { ? ? ? ? ? ? ? ? try { ? ? ? ? ? ? ? ? ? ? socket = new Socket(ip, port); ? ? ? ? ? ? ? ? ? ? setTip("已連接"); ? ? ? ? ? ? ? ? ? ? // 存儲(chǔ)當(dāng)前輸入的 ip ? ? ? ? ? ? ? ? ? ? mainActivity.setMyIp(); ? ? ? ? ? ? ? ? ? ? sendMes("join|"); ? ? ? ? ? ? ? ? ? ? new MyThread().start(); ? ? ? ? ? ? ? ? } catch (IOException e) { ? ? ? ? ? ? ? ? ? ? e.printStackTrace(); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? }, 0); ? ? } ? ? private boolean isWin() { ? ? ? ? return isCanLink(); ? ? } ? ? private boolean isCanLink() { ? ? ? ? // 黑棋先,服務(wù)端為黑棋,客戶端為白棋 ? ? ? ? // 判斷最后下的是誰 ? ? ? ? int who = allList.size() % 2; ? ? ? ? String[] t = allList.get(allList.size() - 1).split("\\|"); ? ? ? ? int r1 = Integer.valueOf(t[0]); ? ? ? ? int c1 = Integer.valueOf(t[1]); ? ? ? ? if (canVLink(who, r1, c1)) { ? ? ? ? ? ? return true; ? ? ? ? } ? ? ? ? if (canHLink(who, r1, c1)) { ? ? ? ? ? ? return true; ? ? ? ? } ? ? ? ? if (canLeftObliqueLink(who, r1, c1)) { ? ? ? ? ? ? return true; ? ? ? ? } ? ? ? ? if (canRightObliqueLink(who, r1, c1)) { ? ? ? ? ? ? return true; ? ? ? ? } ? ? ? ? return false; ? ? } ? ? private boolean canRightObliqueLink(int who, int r1, int c1) { ? ? ? ? int count = 0; ? ? ? ? int r2; ? ? ? ? int c2; ? ? ? ? if (who == 0) { ? ? ? ? ? ? // left top ? ? ? ? ? ? r2 = r1 - 1; ? ? ? ? ? ? c2 = c1 - 1; ? ? ? ? ? ? while (myList.contains(r2 + "|" + c2)) { ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? r2--; ? ? ? ? ? ? ? ? c2--; ? ? ? ? ? ? } ? ? ? ? ? ? // right down ? ? ? ? ? ? r2 = r1 + 1; ? ? ? ? ? ? c2 = c1 + 1; ? ? ? ? ? ? while (myList.contains(r2 + "|" + c2)) { ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? r2++; ? ? ? ? ? ? ? ? c2++; ? ? ? ? ? ? } ? ? ? ? ? ? if (count >= 4) { ? ? ? ? ? ? ? ? return true; ? ? ? ? ? ? } ? ? ? ? } else { ? ? ? ? ? ? // right top ? ? ? ? ? ? r2 = r1 - 1; ? ? ? ? ? ? c2 = c1 - 1; ? ? ? ? ? ? while (enemyList.contains(r2 + "|" + c2)) { ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? r2--; ? ? ? ? ? ? ? ? c2--; ? ? ? ? ? ? } ? ? ? ? ? ? // left down ? ? ? ? ? ? r2 = r1 + 1; ? ? ? ? ? ? c2 = c1 + 1; ? ? ? ? ? ? while (enemyList.contains(r2 + "|" + c2)) { ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? r2++; ? ? ? ? ? ? ? ? c2++; ? ? ? ? ? ? } ? ? ? ? ? ? if (count >= 4) { ? ? ? ? ? ? ? ? return true; ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? return false; ? ? } ? ? private boolean canLeftObliqueLink(int who, int r1, int c1) { ? ? ? ? int count = 0; ? ? ? ? int r2; ? ? ? ? int c2; ? ? ? ? if (who == 0) { ? ? ? ? ? ? // right top ? ? ? ? ? ? r2 = r1 - 1; ? ? ? ? ? ? c2 = c1 + 1; ? ? ? ? ? ? while (myList.contains(r2 + "|" + c2)) { ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? r2--; ? ? ? ? ? ? ? ? c2++; ? ? ? ? ? ? } ? ? ? ? ? ? // left down ? ? ? ? ? ? r2 = r1 + 1; ? ? ? ? ? ? c2 = c1 - 1; ? ? ? ? ? ? while (myList.contains(r2 + "|" + c2)) { ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? r2++; ? ? ? ? ? ? ? ? c2--; ? ? ? ? ? ? } ? ? ? ? ? ? if (count >= 4) { ? ? ? ? ? ? ? ? return true; ? ? ? ? ? ? } ? ? ? ? } else { ? ? ? ? ? ? // right top ? ? ? ? ? ? r2 = r1 - 1; ? ? ? ? ? ? c2 = c1 + 1; ? ? ? ? ? ? while (enemyList.contains(r2 + "|" + c2)) { ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? r2--; ? ? ? ? ? ? ? ? c2++; ? ? ? ? ? ? } ? ? ? ? ? ? // left down ? ? ? ? ? ? r2 = r1 + 1; ? ? ? ? ? ? c2 = c1 - 1; ? ? ? ? ? ? while (enemyList.contains(r2 + "|" + c2)) { ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? r2++; ? ? ? ? ? ? ? ? c2--; ? ? ? ? ? ? } ? ? ? ? ? ? if (count >= 4) { ? ? ? ? ? ? ? ? return true; ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? return false; ? ? } ? ? private boolean canHLink(int who, int r1, int c1) { ? ? ? ? int count = 0; ? ? ? ? int c2; ? ? ? ? if (who == 0) { ? ? ? ? ? ? // left ? ? ? ? ? ? c2 = c1 - 1; ? ? ? ? ? ? while (myList.contains(r1 + "|" + c2)) { ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? c2--; ? ? ? ? ? ? } ? ? ? ? ? ? // right ? ? ? ? ? ? c2 = c1 + 1; ? ? ? ? ? ? while (myList.contains(r1 + "|" + c2)) { ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? c2++; ? ? ? ? ? ? } ? ? ? ? ? ? if (count >= 4) { ? ? ? ? ? ? ? ? return true; ? ? ? ? ? ? } ? ? ? ? } else { ? ? ? ? ? ? // left ? ? ? ? ? ? c2 = c1 - 1; ? ? ? ? ? ? while (enemyList.contains(r1 + "|" + c2)) { ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? c2--; ? ? ? ? ? ? } ? ? ? ? ? ? // right ? ? ? ? ? ? c2 = c1 + 1; ? ? ? ? ? ? while (enemyList.contains(r1 + "|" + c2)) { ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? c2++; ? ? ? ? ? ? } ? ? ? ? ? ? if (count >= 4) { ? ? ? ? ? ? ? ? return true; ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? return false; ? ? } ? ? private boolean canVLink(int who, int r1, int c1) { ? ? ? ? int count = 0; ? ? ? ? int r2; ? ? ? ? if (who == 0) { ? ? ? ? ? ? // top ? ? ? ? ? ? r2 = r1 - 1; ? ? ? ? ? ? while (myList.contains(r2 + "|" + c1)) { ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? r2--; ? ? ? ? ? ? } ? ? ? ? ? ? // down ? ? ? ? ? ? r2 = r1 + 1; ? ? ? ? ? ? while (myList.contains(r2 + "|" + c1)) { ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? r2++; ? ? ? ? ? ? } ? ? ? ? ? ? if (count >= 4) { ? ? ? ? ? ? ? ? return true; ? ? ? ? ? ? } ? ? ? ? } else { ? ? ? ? ? ? // top ? ? ? ? ? ? r2 = r1 - 1; ? ? ? ? ? ? while (enemyList.contains(r2 + "|" + c1)) { ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? r2--; ? ? ? ? ? ? } ? ? ? ? ? ? // down ? ? ? ? ? ? r2 = r1 + 1; ? ? ? ? ? ? while (enemyList.contains(r2 + "|" + c1)) { ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? r2++; ? ? ? ? ? ? } ? ? ? ? ? ? if (count >= 4) { ? ? ? ? ? ? ? ? return true; ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? return false; ? ? } ? ? class MyThread extends Thread { ? ? ? ? @Override ? ? ? ? public void run() { ? ? ? ? ? ? // move|r|c ? ? ? ? ? ? // join| ? ? ? ? ? ? // conn| ? ? ? ? ? ? // quit ? ? ? ? ? ? BufferedReader br = null; ? ? ? ? ? ? InputStreamReader isr = null; ? ? ? ? ? ? try { ? ? ? ? ? ? ? ? String t; ? ? ? ? ? ? ? ? while (true) { ? ? ? ? ? ? ? ? ? ? sleep(100); ? ? ? ? ? ? ? ? ? ? isr = new InputStreamReader(socket.getInputStream()); ? ? ? ? ? ? ? ? ? ? br = new BufferedReader(isr); ? ? ? ? ? ? ? ? ? ? if (br.ready()) { ? ? ? ? ? ? ? ? ? ? ? ? String cmd = br.readLine(); ? ? ? ? ? ? ? ? ? ? ? ? String[] array = cmd.split("\\|"); ? ? ? ? ? ? ? ? ? ? ? ? switch (array[0]) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? case "conn": ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 客戶端一定為白棋 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? player = WHITE; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 主機(jī)先下 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? canPlay = false; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? setTip("對方下"); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mainActivity.runOnUiThread(new Runnable() { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @Override ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? public void run() { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? btnRestart.setEnabled(true); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Toast.makeText(mainActivity, "你是白棋", Toast.LENGTH_SHORT).show(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? ? ? ? ? ? ? case "move": ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? t = array[1] + "|" + array[2]; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? allList.add(t); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? enemyList.add(t); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? canPlay = true; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? setTip("我下"); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (isWin()) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? post(new Runnable() { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @Override ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? public void run() { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Toast.makeText(getContext(), "黑棋獲勝!", Toast.LENGTH_SHORT).show(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? tvTip.setText("對方獲勝!"); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? canPlay = false; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? invalidate(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? ? ? ? ? ? ? case "restart": ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? restartGame(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? ? ? ? ? ? ? case "win": ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? ? ? ? ? ? ? case "quit": ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } catch (IOException e) { ? ? ? ? ? ? ? ? e.printStackTrace(); ? ? ? ? ? ? } catch (InterruptedException e) { ? ? ? ? ? ? ? ? e.printStackTrace(); ? ? ? ? ? ? } ? ? ? ? } ? ? } ? ? private void sendMes(final String s) { ? ? ? ? new Thread(new Runnable() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public void run() { ? ? ? ? ? ? ? ? try { ? ? ? ? ? ? ? ? ? ? pw = new PrintWriter(socket.getOutputStream()); ? ? ? ? ? ? ? ? ? ? pw.println(s); ? ? ? ? ? ? ? ? ? ? pw.flush(); ? ? ? ? ? ? ? ? } catch (IOException e) { ? ? ? ? ? ? ? ? ? ? e.printStackTrace(); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? }).start(); ? ? } ? ? private void initMap() { ? ? ? ? allList.clear(); ? ? ? ? myList.clear(); ? ? ? ? enemyList.clear(); ? ? } ? ? @Override ? ? protected void onDraw(Canvas canvas) { ? ? ? ? super.onDraw(canvas); ? ? ? ? // draw background ? ? ? ? Paint paint = new Paint(); ? ? ? ? paint.setColor(Color.parseColor("#FFE869")); ? ? ? ? canvas.drawRect(0, TOP, 1080, 1400 + TOP, paint); ? ? ? ? // draw line ? ? ? ? paint.setColor(Color.BLACK); ? ? ? ? paint.setStrokeWidth(3); ? ? ? ? for (int i = 0; i < L; i++) { ? ? ? ? ? ? int hx = MARGINLEFT; ? ? ? ? ? ? int hy = MARGINTOP + i * W; ? ? ? ? ? ? int vx = MARGINLEFT + i * W; ? ? ? ? ? ? int vy = MARGINTOP; ? ? ? ? ? ? canvas.drawLine(hx, hy, MARGINLEFT + width, hy, paint); ? ? ? ? ? ? canvas.drawLine(vx, vy, vx, MARGINTOP + height, paint); ? ? ? ? } ? ? ? ? RectF rectF = new RectF(); ? ? ? ? for (int i = 0; i < 3; i++) { ? ? ? ? ? ? for (int j = 0; j < 3; j++) { ? ? ? ? ? ? ? ? int w = 20; ? ? ? ? ? ? ? ? int x = MARGINLEFT + W * 3 + j * W * 4 - w / 2; ? ? ? ? ? ? ? ? int y = MARGINTOP + W * 3 + i * W * 4 - w / 2; ? ? ? ? ? ? ? ? rectF.set(x, y, x + 20, y + 20); ? ? ? ? ? ? ? ? canvas.drawOval(rectF, paint); ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? // draw chess ? ? ? ? String[] t; ? ? ? ? int r, c; ? ? ? ? for (int i = 0; i < allList.size(); i++) { ? ? ? ? ? ? if (i % 2 == 0) { ? ? ? ? ? ? ? ? paint.setColor(Color.BLACK); ? ? ? ? ? ? } else { ? ? ? ? ? ? ? ? paint.setColor(Color.WHITE); ? ? ? ? ? ? } ? ? ? ? ? ? t = allList.get(i).split("\\|"); ? ? ? ? ? ? r = Integer.valueOf(t[0]); ? ? ? ? ? ? c = Integer.valueOf(t[1]); ? ? ? ? ? ? c = MARGINLEFT + c * W - CHESSW / 2; ? ? ? ? ? ? r = MARGINTOP + r * W - CHESSW / 2; ? ? ? ? ? ? rectF.set(c, r, c + CHESSW, r + CHESSW); ? ? ? ? ? ? canvas.drawOval(rectF, paint); ? ? ? ? } ? ? } ? ? private void setTip(final String s) { ? ? ? ? post(new Runnable() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public void run() { ? ? ? ? ? ? ? ? tvTip.setText(s); ? ? ? ? ? ? } ? ? ? ? }); ? ? } ? ? public void restartGame() { ? ? ? ? allList.clear(); ? ? ? ? myList.clear(); ? ? ? ? enemyList.clear(); ? ? ? ? canPlay = false; ? ? ? ? setTip("對方下"); ? ? ? ? post(new Runnable() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public void run() { ? ? ? ? ? ? ? ? invalidate(); ? ? ? ? ? ? } ? ? ? ? }); ? ? } }
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- android自定義View實(shí)現(xiàn)簡單五子棋游戲
- Android自定義view之圍棋動(dòng)畫效果的實(shí)現(xiàn)
- 基于android實(shí)現(xiàn)五子棋開發(fā)
- Android自定義View實(shí)現(xiàn)五子棋游戲
- Android自定義View實(shí)現(xiàn)五子棋小游戲
- android簡單自定義View實(shí)現(xiàn)五子棋
- Android自定義View實(shí)現(xiàn)五子棋游戲
- Android開發(fā)實(shí)現(xiàn)的簡單五子棋游戲示例
- Android游戲開發(fā)之黑白棋
- Android實(shí)現(xiàn)中國象棋游戲(局域網(wǎng)版)
相關(guān)文章
Android實(shí)現(xiàn)相冊中圖片上傳或下載
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)相冊中圖片上傳或下載,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-05-05Android系統(tǒng)檢測程序內(nèi)存占用各種方法
這篇文章主要介紹了Android系統(tǒng)檢測程序內(nèi)存占用各種方法,本文講解了檢查系統(tǒng)總內(nèi)存、檢查某個(gè)程序的各類型內(nèi)存占用、檢查程序狀態(tài)、檢查程序各部分的內(nèi)存占用等內(nèi)容,需要的朋友可以參考下2015-03-03Android動(dòng)態(tài)修改ToolBar的Menu菜單示例
本篇文章主要介紹了Android動(dòng)態(tài)修改ToolBar的Menu菜單示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-02-02Android中Binder詳細(xì)學(xué)習(xí)心得
這篇文章主要介紹了Android中Binder詳細(xì)學(xué)習(xí)心得,并分析了Binder的詳細(xì)用法,需要的朋友參考下吧。2018-01-01Android實(shí)現(xiàn)ViewFlipper圖片動(dòng)畫滑動(dòng)
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)ViewFlipper圖片動(dòng)畫滑動(dòng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05Android實(shí)現(xiàn)強(qiáng)制下線功能的示例代碼
這篇文章主要介紹了Android實(shí)現(xiàn)強(qiáng)制下線功能的示例代碼,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07Android開發(fā)Intent跳轉(zhuǎn)傳遞list集合實(shí)現(xiàn)示例
這篇文章主要為大家介紹了Android開發(fā)Intent跳轉(zhuǎn)傳遞list集合實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07Android編程實(shí)現(xiàn)TextView部分顏色變動(dòng)的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)TextView部分顏色變動(dòng)的方法,涉及Android針對TextView樣式操作的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11