您好,登錄后才能下訂單哦!
這篇文章主要介紹“Android如何實現五子棋游戲局域網版”,在日常操作中,相信很多人在Android如何實現五子棋游戲局域網版問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Android如何實現五子棋游戲局域網版”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
實現環境: android studio 3.2.1, 手機分辨率為: 1920 * 1080
局域網采用 Socket 連接
分主活動類,主機類,客戶端類
代碼如下
清單文件要添加的權限:
<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 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")); // 顯示本機的 ip 地址 setIp(); // 根據按鈕來判斷作為主機還是客戶端 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(); // 將當前控件隱藏掉 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(); // 將當前控件隱藏掉 viewGone(); } }); } // 存儲當前輸入的 ip public void setMyIp() { setPreference("myIp", ipText.getText().toString()); } // 用于獲取本機 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(); // 只獲取局域網地址 if ("192".equals(s.substring(0, 3))) { txtMain.setText(txtMain.getText().toString() + " 主機ip: " + s); } } } } } catch (SocketException e) { e.printStackTrace(); } } // 隱藏主活動的輔助空間 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."); } // 用于存儲數據到本地 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="作為主機" 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>
主機類:
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個格子,15條行列坐標 public static final int L = 15; public static final int BLOCKL = 14; // 棋的顏色標記 public static final int BLACK = 2, WHITE = 1; // public static final int NULL = -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 ServerSocket serverSocket; // 用于與客戶端交互 private Socket socket; // 對方端口 private int port; // 用于發送消息 private PrintWriter pw; // 主活動 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(); // 發送消息給客戶端 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) { // 獲取當前點擊位置的 x, y 坐標 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; } // 轉化為棋盤的 col 列坐標 // x % W > W / 2 ? 1 : 0 為當前的位置的求模后是否滿足大于一半的寬度, // 若大于則把它安排到下一個位置,否則不變 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("我方獲勝!"); } } } return true; } }); } // 開啟服務器 public void startConn() { // 只能在線程(異步)中執行 new Timer().schedule(new TimerTask() { @Override public void run() { try { serverSocket = new ServerSocket(port); // 獲取客戶端信息,若無客戶端連接則會一直暫停在這 socket = serverSocket.accept(); setTip("連接成功!"); // 發送已連接給客戶端 sendMes("conn|"); // 開啟接受消息的線程 new MyThread().start(); // 更新視圖 invalidate(); } catch (IOException e) { e.printStackTrace(); } } }, 0); } // 是否贏了 private boolean isWin() { // 好像有點多此一舉... return isCanLink(); } // 是否有了輸贏 private boolean isCanLink() { // 黑棋先,服務端為黑棋,客戶端為白棋 // 判斷最后下的是誰,為0為白棋,為1為黑棋 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 == 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++; } // 若有四個以上則代表構成五子 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 == 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) { // 睡眠一段時間,不必每毫秒都執行 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 "join": // 服務器一定為黑棋 player = BLACK; // 我方先下 canPlay = true; // 發送消息給客戶端 sendMes("conn|"); setTip("我下"); // UI 更新一定在主線程中執行 // 重新開始按鈕可以點了,這個方法可以賺到主線程中 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": // 存儲對方走的棋坐標 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); } }); } // 發送消息個客戶端 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(); } // 調用 invalidate 是執行 @Override protected void onDraw(Canvas canvas) { // 畫筆,設置線條的樣式 Paint paint = new Paint(); paint.setColor(Color.parseColor("#FFE869")); // 設置棋盤的位置,視情況而定 canvas.drawRect(0, TOP, 1080, 1400 + TOP, paint); // 設置畫筆顏色為黑色,用于畫棋盤坐標系 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); } } // 畫棋子 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); } } // 重新開始游戲 public void restartGame() { allList.clear(); myList.clear(); enemyList.clear(); canPlay = true; setTip("我下"); post(new Runnable() { @Override public void run() { invalidate(); } }); } }
客戶端類: 與主機有區別的地方就是 建立連接和接受消息的線程,其它的地方大體相同
代碼如下:
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個格子,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("已連接"); // 存儲當前輸入的 ip mainActivity.setMyIp(); sendMes("join|"); new MyThread().start(); } catch (IOException e) { e.printStackTrace(); } } }, 0); } private boolean isWin() { return isCanLink(); } private boolean isCanLink() { // 黑棋先,服務端為黑棋,客戶端為白棋 // 判斷最后下的是誰 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; // 主機先下 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(); } }); } }
到此,關于“Android如何實現五子棋游戲局域網版”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。