本篇將實作創建8 * 8個棋子(chessman)與8 * 8棋子選擇格(chessmanSelect)以及監聽點擊棋子移動的按鈕監聽器,以及實作完成整個getSuccess()
我們回到getSuccess(),取得棋子資料後,會先創建8 * 8棋子,以及8 * 8棋子選擇格
chessman = createBoard.createChessmanAndChessmanSelect(grid_playerChessman,grid_playerChessmanSelect,chessboardData,chessmanEnable).get(0);
chessmanSelect = createBoard.createChessmanAndChessmanSelect(grid_playerChessman,grid_playerChessmanSelect,chessboardData,chessmanEnable).get(1);
並使用兩個陣列接收:
private ArrayList<Button> chessman = new ArrayList<>();
private ArrayList<TextView> chessmanSelect = new ArrayList<>();
這裡我們呼叫createBoard中的createChessmanAndChessmanSelect方法來創建,所以我們到createBoard中實作方法
public ArrayList<ArrayList> createChessmanAndChessmanSelect(GridLayout grid_playerChessman,
GridLayout grid_playerChessmanSelect,
HashMap<String,Object> chessboardData,
Boolean chessmanEnable){
ArrayList callbackArray = new ArrayList();
// 設定GridLayout的列數和行數
grid_playerChessman.setColumnCount(8);
grid_playerChessman.setRowCount(8);
grid_playerChessmanSelect.setColumnCount(8);
grid_playerChessmanSelect.setRowCount(8);
// 動態建立Button並添加到GridLayout中
for (int i = 0; i < 64; i++) {
chessman.add(new Button(activity));
chessmanSelect.add(new TextView(activity));
// 讀取螢幕大小,並根據大小調整按鈕比例
DisplayMetrics displayMetrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int newWidth = (int) (displayMetrics.widthPixels * 0.1f);
int newHeight = (int) (newWidth);
int newMarginsWidth = (int) (displayMetrics.widthPixels * 0);
int newMarginsHeight = (int) (newMarginsWidth);
// 設定Button的Layout參數
GridLayout.LayoutParams params = new GridLayout.LayoutParams();
if(grid_playerChessman != null || grid_playerChessmanSelect != null){
grid_playerChessman.removeView(chessman.get(i));
grid_playerChessmanSelect.removeView(chessmanSelect.get(i));
}
params.width = newWidth;
params.height = newHeight;
params.setMargins(newMarginsWidth, newMarginsHeight, newMarginsWidth, newMarginsHeight);
chessman.get(i).setTypeface(null, Typeface.BOLD);
chessmanSelect.get(i).setTypeface(null, Typeface.BOLD);
params.setGravity(Gravity.CENTER);
// 設定Button的列和行位置
params.rowSpec = GridLayout.spec(i / 8);
params.columnSpec = GridLayout.spec(i % 8);
chessman.get(i).setBackgroundResource(playerChessboardData.getIntChessmanData((String) chessboardData.get(playerChessboardData.getStringBoardData(i))));
// 將Button添加到GridLayout中
grid_playerChessmanSelect.addView(chessmanSelect.get(i),params);
grid_playerChessman.addView(chessman.get(i),params);
if(chessmanEnable == false){
chessman.get(i).setEnabled(false);
}else{
chessman.get(i).setEnabled(true);
}
callbackArray.add(chessman);
callbackArray.add(chessmanSelect);
}
return callbackArray;
}
這裡我們同時創建8 * 8棋子,以及8 * 8棋子選擇格,並將結果以陣列回傳,所以我們取得資料時會get(0)和get(1)
接著就是監聽棋子,會取得點擊哪個位置格的棋子,得到索引i,並交給selectChessmanListen():
for(int i=0;i<64;i++){
chessman.get(i).setOnClickListener(selectChessmanListen(i));
}
設置2個全域變數startChessman、stopChessman,初值為99,當選擇起手格子後會將position設置給startChessman,當選擇目標格子後會將position設置給stopChessman
基本流程如下:
public View.OnClickListener selectChessmanListen(int position){
// 選擇棋子移動
return new View.OnClickListener(){
@Override
public void onClick(View v){
// 未選擇起始格
if(startChessman == 99 && stopChessman == 99){
allMoveList = new ArrayList();
if(chessmanMove.choice(position,chessboardData,pawnMove1,pawnMove2,castlingMove1)!=null
&& chessmanMove.choice(position,chessboardData,pawnMove1,pawnMove2,castlingMove1).size()!=0){
allMoveList = chessmanMove.choice(position,chessboardData,pawnMove1,pawnMove2,castlingMove1);
startChessman = position;
chessmanSelect.get(position).setBackgroundResource(R.drawable.redline);
for(int i=0;i<allMoveList.size();i++){
chessmanSelect.get((int)allMoveList.get(i)).setBackgroundResource(R.drawable.greenline);
}
}
}
// 選擇起始格,未選擇目標格
else if(startChessman != 99 && stopChessman == 99){
if(position == startChessman){
clearData();
}else{
isCanMove(position);
}
}
// 起始格與目標格都已選擇
else if(startChessman != 99 && stopChessman != 99){
if(position == startChessman){
clearData();
} else if (position == stopChessman) {
for(int i=0;i<64;i++){
chessman.get(i).setEnabled(false);
}
move();
} else{
isCanMove(position);
}
}
}
};
}
清除資料相當於初始化
public void clearData(){
startChessman = 99;
stopChessman = 99;
castling = "";
moveTwoStep = "";
inPassing = "";
getCount = 0;
isPromotion = false;
for(int i=0;i<64;i++){
chessmanSelect.get(i).setBackgroundResource(R.drawable.blank);
}
}
這裡負責判斷點擊的目標格是否為可選格,如果是則將position設置給stopChessman,若不是則印出系統訊息
public void isCanMove(int position){
castling = "";
inPassing = "";
if(chessboardData.get(playerChessboardData.getStringBoardData(startChessman)).equals("wP")){
ArrayList greenArray = new ArrayList();
greenArray.addAll(canMoveList);
greenArray.addAll(canMoveTwoStepList);
greenArray.addAll(canEpMoveList);
greenArray.addAll(canEatList);
for(int i=0;i<greenArray.size();i++){
chessmanSelect.get((int)greenArray.get(i)).setBackgroundResource(R.drawable.greenline);
}
if(position+8 == startChessman){
for(int i=0;i<allMoveList.size();i++){
if(position == (int)allMoveList.get(i) && chessboardData.get(playerChessboardData.getStringBoardData(position)).equals(" ")){
stopChessman = position;
chessmanSelect.get(position).setBackgroundResource(R.drawable.redline);
// break;
}
}
} else if (position+16 == startChessman) {
for(int i=0;i<allMoveList.size();i++){
if(position == (int)allMoveList.get(i) && chessboardData.get(playerChessboardData.getStringBoardData(position)).equals(" ")){
stopChessman = position;
moveTwoStep=playerChessboardData.getStringBoardData(position);
chessmanSelect.get(position).setBackgroundResource(R.drawable.redline);
// break;
}
}
} else if(position+9==startChessman || position+7==startChessman){
for(int i=0;i<allMoveList.size();i++){
if(position == (int)allMoveList.get(i) && chessboardData.get(playerChessboardData.getStringBoardData(position)).equals(" ")){
stopChessman = position;
chessmanSelect.get(position).setBackgroundResource(R.drawable.redline);
inPassing = playerChessboardData.getStringBoardData(position+8);
// break;
}
}
for(int i=0;i<allMoveList.size();i++){
if(position == (int)allMoveList.get(i) && String.valueOf(chessboardData.get(playerChessboardData.getStringBoardData(position)).toString().charAt(0)).equals("b")){
stopChessman = position;
chessmanSelect.get(position).setBackgroundResource(R.drawable.redline);
// break;
}
}
} else{
}
}else if(chessboardData.get(playerChessboardData.getStringBoardData(startChessman)).equals("wK")){
for(int i=0;i<allMoveList.size();i++){
chessmanSelect.get((int)allMoveList.get(i)).setBackgroundResource(R.drawable.greenline);
}
for(int i=0;i<allMoveList.size();i++){
chessmanSelect.get((int)allMoveList.get(i)).setBackgroundResource(R.drawable.greenline);
}
if(allMoveList.size() != 0){
for(int i=0;i<allMoveList.size();i++){
if(position == (int)allMoveList.get(i)){
if(position == 58){
stopChessman = position;
chessmanSelect.get(position).setBackgroundResource(R.drawable.redline);
castling = "leftCastling";
}else if(position == 62){
stopChessman = position;
chessmanSelect.get(position).setBackgroundResource(R.drawable.redline);
castling = "rightCastling";
}
}
}
}
for(int i=0;i<allMoveList.size();i++){
if(position == (int)allMoveList.get(i)){
if(chessboardData.get(playerChessboardData.getStringBoardData(position)).equals(" ")
|| String.valueOf(chessboardData.get(playerChessboardData.getStringBoardData(position)).toString().charAt(0)).equals("b")){
stopChessman = position;
chessmanSelect.get(position).setBackgroundResource(R.drawable.redline);
// break;
}else{
systemMessage("系統訊息:\n不可移動");
}
}
}
}else{
for(int i=0;i<allMoveList.size();i++){
chessmanSelect.get((int)allMoveList.get(i)).setBackgroundResource(R.drawable.greenline);
if(position == (int)allMoveList.get(i)){
if(chessboardData.get(playerChessboardData.getStringBoardData(position)).equals(" ")
|| String.valueOf(chessboardData.get(playerChessboardData.getStringBoardData(position)).toString().charAt(0)).equals("b")){
stopChessman = position;
chessmanSelect.get(position).setBackgroundResource(R.drawable.redline);
// break;
}else{
systemMessage("系統訊息:\n不可移動");
}
}
}
}
}
回到getSuccess(),我們在此也會做其他判斷,像是城堡或國王是否移動過,以及顯示出棋譜文字
public void isKorRMove(){
if(!(chessboardData.get("a1").equals("wR"))){
castlingMove1.put("a1",false);
dbp.uploadData(roomKey,"CastlingMove1",castlingMove1);
}
if(!(chessboardData.get("h1").equals("wR"))){
castlingMove1.put("h1",false);
dbp.uploadData(roomKey,"CastlingMove1",castlingMove1);
}
if(!(chessboardData.get("e1").equals("wK"))){
castlingMove1.put("e1",false);
dbp.uploadData(roomKey,"CastlingMove1",castlingMove1);
}
}
顯示文字
public void showText(){
tv_message.setText(player2message);
String showMoveData="";
String state="";
for(int i=1;i<chessmanMoveData.size();i++){
if(i%2==1){
state="白";
}else{
state="黑";
}
showMoveData = showMoveData +"\n"+i+"("+state+")"+" : "+chessmanMoveData.get(String.valueOf(i));
}
tv_moveData.setText(showMoveData);
}
所以整個getSuccess方法會是:
public void getSuccess(String getId,
String getRoomNumber,
Boolean getPlayer1OnlineState,
Boolean getPlayer2OnlineState,
String getMoveState,
HashMap<String,Object> getChessboardData,
HashMap<String,Object> getChessmanMoveData,
String getTurn,
HashMap<String,Object> getPawnMove1,
HashMap<String,Object> getPawnMove2,
HashMap<String,Object> getCastlingMove1,
HashMap<String,Object> getCastlingMove2,
String getDate,
String getPlayer1message,
String getPlayer2message,
String getWinPlayer){
Log.d("TAG", "資料獲取成功");
roomKey = getId;
player1OnlineState = getPlayer1OnlineState;
player2OnlineState = getPlayer2OnlineState;
moveState = getMoveState;
chessboardData = getChessboardData;
chessmanMoveData = getChessmanMoveData;
turn = Integer.parseInt(getTurn);
pawnMove1 = getPawnMove1;
pawnMove2 = getPawnMove2;
castlingMove1 = getCastlingMove1;
castlingMove2 = getCastlingMove2;
date = getDate;
player1message = getPlayer1message;
player2message = getPlayer2message;
winPlayer = getWinPlayer;
getCount+=1;
// Log.d("20240318", "getSuccess: "+roomKey);
// 判斷King或Rook是否移動過
isKorRMove();
// 設置訊息文字、棋譜文字
showText();
chessman = createBoard.createChessmanAndChessmanSelect(grid_playerChessman,grid_playerChessmanSelect,chessboardData,chessmanEnable).get(0);
chessmanSelect = createBoard.createChessmanAndChessmanSelect(grid_playerChessman,grid_playerChessmanSelect,chessboardData,chessmanEnable).get(1);
if(gameMode.equals("ai") && moveState.equals("black") && getCount==1){
gptMove.setRoomKey(roomKey);
gptMove.setTurn(String.valueOf(turn));
gptMove.setCastling(castling);
gptMove.setChessmanMoveData(chessmanMoveData);
gptMove.setChessboardData(chessboardData);
gptMove.setGPT();
}
for(int i=0;i<64;i++){
chessman.get(i).setOnClickListener(selectChessmanListen(i));
}
}
下一篇我們介紹PlayerChessmanMoveData中核心的choice方法