本文主要内容:python Pygame alpha-beta剪枝算法 玩中国象棋 相当于入门水平,我还是能下赢它
完整简洁并有详细注释的代码:
python Pygame alpha-beta剪枝算法 玩中国象棋 相当于入门水平
运行入口为:chinachess.py
算法和代码解释请查看参考文献里的文章

1、界面演示

2、关键代码

可视化中国象棋运行入口

import time
import pygame
import ChinaChess.constants
from ChinaChess import constants, pieces, computer
import ChinaChess.computer
import ChinaChess.my_game as mg'''
此文件为可视化中国象棋运行入口
'''class MainGame():window = NoneStart_X = ChinaChess.constants.Start_XStart_Y = ChinaChess.constants.Start_YLine_Span = ChinaChess.constants.Line_SpanMax_X = Start_X + 8 * Line_SpanMax_Y = Start_Y + 9 * Line_Spanfrom_x = 0from_y = 0to_x = 0to_y = 0clickx = -1clicky = -1mgInit = mg.my_game()player1Color = constants.player1Colorplayer2Color = constants.player2ColorPutdownflag = player1ColorpiecesSelected = NonepiecesList = []def start_game(self):MainGame.window = pygame.display.set_mode([constants.SCREEN_WIDTH, constants.SCREEN_HEIGHT])pygame.display.set_caption("中国象棋")# 把所有棋子摆好self.piecesInit()while True:time.sleep(0.1)# 获取事件MainGame.window.fill(constants.BG_COLOR)self.drawChessboard()# 遍历所有棋子,显示所有棋子self.piecesDisplay()# 判断游戏胜利self.VictoryOrDefeat()# 轮到电脑了self.Computerplay()# 获取所有的事件self.getEvent()pygame.display.update()pygame.display.flip()def drawChessboard(self):mid_end_y = MainGame.Start_Y + 4 * MainGame.Line_Spanmin_start_y = MainGame.Start_Y + 5 * MainGame.Line_Spanfor i in range(0, 9):x = MainGame.Start_X + i * MainGame.Line_Spanif i == 0 or i == 8:pygame.draw.line(MainGame.window, constants.BLACK, [x, MainGame.Start_Y], [x, MainGame.Max_Y], 1)else:pygame.draw.line(MainGame.window, constants.BLACK, [x, MainGame.Start_Y], [x, mid_end_y], 1)pygame.draw.line(MainGame.window, constants.BLACK, [x, min_start_y], [x, MainGame.Max_Y], 1)for i in range(0, 10):y = MainGame.Start_Y + i * MainGame.Line_Spanpygame.draw.line(MainGame.window, constants.BLACK, [MainGame.Start_X, y], [MainGame.Max_X, y], 1)speed_dial_start_x = MainGame.Start_X + 3 * MainGame.Line_Spanspeed_dial_end_x = MainGame.Start_X + 5 * MainGame.Line_Spanspeed_dial_y1 = MainGame.Start_Y + 0 * MainGame.Line_Spanspeed_dial_y2 = MainGame.Start_Y + 2 * MainGame.Line_Spanspeed_dial_y3 = MainGame.Start_Y + 7 * MainGame.Line_Spanspeed_dial_y4 = MainGame.Start_Y + 9 * MainGame.Line_Spanpygame.draw.line(MainGame.window, constants.BLACK, [speed_dial_start_x, speed_dial_y1],[speed_dial_end_x, speed_dial_y2], 1)pygame.draw.line(MainGame.window, constants.BLACK, [speed_dial_start_x, speed_dial_y2],[speed_dial_end_x, speed_dial_y1], 1)pygame.draw.line(MainGame.window, constants.BLACK, [speed_dial_start_x, speed_dial_y3],[speed_dial_end_x, speed_dial_y4], 1)pygame.draw.line(MainGame.window, constants.BLACK, [speed_dial_start_x, speed_dial_y4],[speed_dial_end_x, speed_dial_y3], 1)def piecesInit(self):MainGame.piecesList.append(pieces.Rooks(MainGame.player2Color, 0, 0))MainGame.piecesList.append(pieces.Rooks(MainGame.player2Color, 8, 0))MainGame.piecesList.append(pieces.Elephants(MainGame.player2Color, 2, 0))MainGame.piecesList.append(pieces.Elephants(MainGame.player2Color, 6, 0))MainGame.piecesList.append(pieces.King(MainGame.player2Color, 4, 0))MainGame.piecesList.append(pieces.Knighs(MainGame.player2Color, 1, 0))MainGame.piecesList.append(pieces.Knighs(MainGame.player2Color, 7, 0))MainGame.piecesList.append(pieces.Cannons(MainGame.player2Color, 1, 2))MainGame.piecesList.append(pieces.Cannons(MainGame.player2Color, 7, 2))MainGame.piecesList.append(pieces.Mandarins(MainGame.player2Color, 3, 0))MainGame.piecesList.append(pieces.Mandarins(MainGame.player2Color, 5, 0))MainGame.piecesList.append(pieces.Pawns(MainGame.player2Color, 0, 3))MainGame.piecesList.append(pieces.Pawns(MainGame.player2Color, 2, 3))MainGame.piecesList.append(pieces.Pawns(MainGame.player2Color, 4, 3))MainGame.piecesList.append(pieces.Pawns(MainGame.player2Color, 6, 3))MainGame.piecesList.append(pieces.Pawns(MainGame.player2Color, 8, 3))MainGame.piecesList.append(pieces.Rooks(MainGame.player1Color, 0, 9))MainGame.piecesList.append(pieces.Rooks(MainGame.player1Color, 8, 9))MainGame.piecesList.append(pieces.Elephants(MainGame.player1Color, 2, 9))MainGame.piecesList.append(pieces.Elephants(MainGame.player1Color, 6, 9))MainGame.piecesList.append(pieces.King(MainGame.player1Color, 4, 9))MainGame.piecesList.append(pieces.Knighs(MainGame.player1Color, 1, 9))MainGame.piecesList.append(pieces.Knighs(MainGame.player1Color, 7, 9))MainGame.piecesList.append(pieces.Cannons(MainGame.player1Color, 1, 7))MainGame.piecesList.append(pieces.Cannons(MainGame.player1Color, 7, 7))MainGame.piecesList.append(pieces.Mandarins(MainGame.player1Color, 3, 9))MainGame.piecesList.append(pieces.Mandarins(MainGame.player1Color, 5, 9))MainGame.piecesList.append(pieces.Pawns(MainGame.player1Color, 0, 6))MainGame.piecesList.append(pieces.Pawns(MainGame.player1Color, 2, 6))MainGame.piecesList.append(pieces.Pawns(MainGame.player1Color, 4, 6))MainGame.piecesList.append(pieces.Pawns(MainGame.player1Color, 6, 6))MainGame.piecesList.append(pieces.Pawns(MainGame.player1Color, 8, 6))def piecesDisplay(self):# 遍历所有棋子,显示所有棋子for item in MainGame.piecesList:item.displaypieces(MainGame.window)# MainGame.window.blit(item.image, item.rect)def getEvent(self):# 获取所有的事件eventList = pygame.event.get()for event in eventList:if event.type == pygame.QUIT:self.endGame()elif event.type == pygame.MOUSEBUTTONDOWN:pos = pygame.mouse.get_pos()mouse_x = pos[0]mouse_y = pos[1]if (mouse_x > MainGame.Start_X - MainGame.Line_Span / 2 and mouse_x < MainGame.Max_X + MainGame.Line_Span / 2) and (mouse_y > MainGame.Start_Y - MainGame.Line_Span / 2 and mouse_y < MainGame.Max_Y + MainGame.Line_Span / 2):print(str(mouse_x) + "" + str(mouse_y))print(str(MainGame.Putdownflag))if MainGame.Putdownflag != MainGame.player1Color:returnclick_x = round((mouse_x - MainGame.Start_X) / MainGame.Line_Span)click_y = round((mouse_y - MainGame.Start_Y) / MainGame.Line_Span)click_mod_x = (mouse_x - MainGame.Start_X) % MainGame.Line_Spanclick_mod_y = (mouse_y - MainGame.Start_Y) % MainGame.Line_Spanif abs(click_mod_x - MainGame.Line_Span / 2) >= 5 and abs(click_mod_y - MainGame.Line_Span / 2) >= 5:print("有效点:x=" + str(click_x) + " y=" + str(click_y))# 有效点击点self.from_x = MainGame.clickxself.from_y = MainGame.clickyself.to_x = click_xself.to_y = click_yprint(self.from_x)print(self.from_y)MainGame.clickx = click_xMainGame.clicky = click_yself.PutdownPieces(MainGame.player1Color, click_x, click_y)else:print("out")def PutdownPieces(self, t, x, y):selectfilter = list(filter(lambda cm: cm.x == x and cm.y == y and cm.player == MainGame.player1Color, MainGame.piecesList))if len(selectfilter):MainGame.piecesSelected = selectfilter[0]returnif MainGame.piecesSelected:print("MainGame.piecesSelected")arr = pieces.listPiecestoArr(MainGame.piecesList)if MainGame.piecesSelected.canmove(arr, x, y):self.PiecesMove(MainGame.piecesSelected, x, y)MainGame.Putdownflag = MainGame.player2Colorelse:fi = filter(lambda p: p.x == x and p.y == y, MainGame.piecesList)listfi = list(fi)if len(listfi) != 0:MainGame.piecesSelected = listfi[0]def PiecesMove(self, pieces, x, y):for item in MainGame.piecesList:if item.x == x and item.y == y:MainGame.piecesList.remove(item)pieces.x = xpieces.y = yprint("move to " + str(x) + " " + str(y))return Truedef Computerplay(self):if MainGame.Putdownflag == MainGame.player2Color:print("轮到电脑了")computermove = computer.getPlayInfo(MainGame.piecesList, self.from_x, self.from_y, self.to_x, self.to_y,self.mgInit)if computer == None:returnpiecemove = Nonefor item in MainGame.piecesList:if item.x == computermove[0] and item.y == computermove[1]:piecemove = itemself.PiecesMove(piecemove, computermove[2], computermove[3])MainGame.Putdownflag = MainGame.player1Color# 判断游戏胜利def VictoryOrDefeat(self):result = [MainGame.player1Color, MainGame.player2Color]for item in MainGame.piecesList:if type(item) == pieces.King:if item.player == MainGame.player1Color:result.remove(MainGame.player1Color)if item.player == MainGame.player2Color:result.remove(MainGame.player2Color)if len(result) == 0:returnif result[0] == MainGame.player1Color:txt = "你失败了哦!"else:txt = "你胜利了哦!"MainGame.window.blit(self.getTextSuface("%s" % txt), (constants.SCREEN_WIDTH - 100, 200))MainGame.Putdownflag = constants.overColordef getTextSuface(self, text):pygame.font.init()print(pygame.font.get_fonts())font = pygame.font.SysFont('kaiti', 18)txt = font.render(text, True, constants.TEXT_COLOR)return txtdef endGame(self):print("退出")exit()if __name__ == '__main__':MainGame().start_game()

非可视化中国象棋运行入口

import ChinaChess.my_chess as mc
import ChinaChess.chess_constants as cc
import numpy as np
'''
此文件为非可视化中国象棋运行入口
'''class HistoryTable:  # 历史启发算法def __init__(self):self.table = np.zeros((2, 90, 90))def get_history_score(self, who,  step):return self.table[who, step.from_x * 9 + step.from_y, step.to_x * 9 + step.to_y]def add_history_score(self, who,  step, depth):self.table[who, step.from_x * 9 + step.from_y, step.to_x * 9 + step.to_y] += 2 << depthclass Relation:def __init__(self):self.chess_type = 0self.num_attack = 0self.num_guard = 0self.num_attacked = 0self.num_guarded = 0self.attack = [0, 0, 0, 0, 0, 0]self.attacked = [0, 0, 0, 0, 0, 0]self.guard = [0, 0, 0, 0, 0, 0]self.guarded = [0, 0, 0, 0, 0, 0]class my_game:def __init__(self):self.board = mc.chess_board()self.max_depth = cc.max_depthself.history_table = HistoryTable()self.best_move = mc.step()self.cnt = 0def alpha_beta(self, depth, alpha, beta):  # alpha-beta剪枝,alpha是大可能下界,beta是最小可能上界who = (self.max_depth - depth) % 2  # 那个玩家if self.is_game_over(who):  # 判断是否游戏结束,如果结束了就不用搜了return cc.min_valif depth == 1:  # 搜到指定深度了,也不用搜了# print(self.evaluate(who))return self.evaluate(who)move_list = self.board.generate_move(who)  # 返回所有能走的方法# 利用历史表0for i in range(len(move_list)):move_list[i].score = self.history_table.get_history_score(who, move_list[i])move_list.sort()  # 为了让更容易剪枝利用历史表得分进行排序# for item in move_list:#     print(item.score)best_step = move_list[0]score_list = []for step in move_list:temp = self.move_to(step)score = -self.alpha_beta(depth - 1, -beta, -alpha)  # 因为是一层选最大一层选最小,所以利用取负号来实现score_list.append(score)self.undo_move(step, temp)if score > alpha:alpha = scoreif depth == self.max_depth:self.best_move = stepbest_step = stepif alpha >= beta:best_step = stepbreak# print(score_list)# 更新历史表if best_step.from_x != -1:self.history_table.add_history_score(who, best_step, depth)return alphadef evaluate(self, who):  # who表示该谁走,返回评分值self.cnt += 1# print('====================================================================================')relation_list = self.init_relation_list()base_val = [0, 0]pos_val = [0, 0]mobile_val = [0, 0]relation_val = [0, 0]for x in range(9):for y in range(10):now_chess = self.board.board[x][y]type = now_chess.chess_typeif type == 0:continue# now = 0 if who else 1now = now_chess.belongpos = x * 9 + ytemp_move_list = self.board.get_chess_move(x, y, now, True)# 计算基础价值base_val[now] += cc.base_val[type]# 计算位置价值if now == 0:  # 如果是要求最大值的玩家pos_val[now] += cc.pos_val[type][pos]else:pos_val[now] += cc.pos_val[type][89 - pos]# 计算机动性价值,记录关系信息for item in temp_move_list:# print('----------------')# print(item)temp_chess = self.board.board[item.to_x][item.to_y]  # 目的位置的棋子if temp_chess.chess_type == cc.kong:  # 如果是空,那么加上机动性值# print('ok')mobile_val[now] += cc.mobile_val[type]# print(mobile_val[now])continueelif temp_chess.belong != now:  # 如果不是自己一方的棋子# print('ok1')if temp_chess.chess_type == cc.jiang:  # 如果能吃了对方的将,那么就赢了if temp_chess.belong != who:# print(self.board.board[item.from_x][item.from_y])# print(temp_chess)# print(item)# print('bug here')return cc.max_valelse:relation_val[1 - now] -= 20  # 如果不能,那么就相当于被将军,对方要减分continue# 记录攻击了谁relation_list[x][y].attack[relation_list[x][y].num_attack] = temp_chess.chess_typerelation_list[x][y].num_attack += 1relation_list[item.to_x][item.to_y].chess_type = temp_chess.chess_type# print(item)# 记录被谁攻击# if item.to_x == 4 and item.to_y == 1:#     print('--------------')#     print(now_chess.chess_type)#     print(item.from_x, item.from_y)#     print('*************')#     print(temp_chess.chess_type)#     print(item.to_x, item.to_y)#     print(relation_list[item.to_x][item.to_y].num_attacked)#     print([relation_list[item.to_x][item.to_y].attacked[j] for j in range(relation_list[item.to_x][item.to_y].num_attacked)])#     if relation_list[item.to_x][item.to_y].num_attacked == 5:#         print('###################')#         self.board.print_board()#         print('###################')relation_list[item.to_x][item.to_y].attacked[relation_list[item.to_x][item.to_y].num_attacked] = typerelation_list[item.to_x][item.to_y].num_attacked += 1elif temp_chess.belong == now:# print('ok2')if temp_chess.chess_type == cc.jiang:  # 保护自己的将没有意义,直接跳过continue# 记录关系信息-guard# print(item)# if item.to_x == 4 and item.to_y == 1:#     print('--------------')#     print(now_chess.chess_type)#     print(item)#     print('*************')#     print(temp_chess.chess_type)#     print(relation_list[item.to_x][item.to_y].num_guarded)#     print([relation_list[item.to_x][item.to_y].guarded[j] for j in range(relation_list[item.to_x][item.to_y].num_guarded)])#     if relation_list[item.to_x][item.to_y].num_guarded == 5:#         print('###################')#         print(x, y, who)#         self.board.print_board(True)#         print('###################')relation_list[x][y].guard[relation_list[x][y].num_guard] = temp_chessrelation_list[x][y].num_guard += 1relation_list[item.to_x][item.to_y].chess_type = temp_chess.chess_typerelation_list[item.to_x][item.to_y].guarded[relation_list[item.to_x][item.to_y].num_guarded] = typerelation_list[item.to_x][item.to_y].num_guarded += 1# relation_list[x][y].chess_type = typefor x in range(9):for y in range(10):num_attacked = relation_list[x][y].num_attackednum_guarded = relation_list[x][y].num_guardednow_chess = self.board.board[x][y]type = now_chess.chess_typenow = now_chess.belongunit_val = cc.base_val[now_chess.chess_type] >> 3sum_attack = 0  # 被攻击总子力sum_guard = 0min_attack = 999  # 最小的攻击者max_attack = 0  # 最大的攻击者max_guard = 0flag = 999  # 有没有比这个子的子力小的if type == cc.kong:continue# 统计攻击方的子力for i in range(num_attacked):temp = cc.base_val[relation_list[x][y].attacked[i]]flag = min(flag, min(temp, cc.base_val[type]))min_attack = min(min_attack, temp)max_attack = max(max_attack, temp)sum_attack += temp# 统计防守方的子力for i in range(num_guarded):temp = cc.base_val[relation_list[x][y].guarded[i]]max_guard = max(max_guard, temp)sum_guard += tempif num_attacked == 0:relation_val[now] += 5 * relation_list[x][y].num_guardedelse:muti_val = 5 if who != now else 1if num_guarded == 0:  # 如果没有保护relation_val[now] -= muti_val * unit_valelse:  # 如果有保护if flag != 999:  # 存在攻击者子力小于被攻击者子力,对方将愿意换子relation_val[now] -= muti_val * unit_valrelation_val[1 - now] -= muti_val * (flag >> 3)# 如果是二换一, 并且最小子力小于被攻击者子力与保护者子力之和, 则对方可能以一子换两子elif num_guarded == 1 and num_attacked > 1 and min_attack < cc.base_val[type] + sum_guard:relation_val[now] -= muti_val * unit_valrelation_val[now] -= muti_val * (sum_guard >> 3)relation_val[1 - now] -= muti_val * (flag >> 3)# 如果是三换二并且攻击者子力较小的二者之和小于被攻击者子力与保护者子力之和,则对方可能以两子换三子elif num_guarded == 2 and num_attacked == 3 and sum_attack - max_attack < cc.base_val[type] + sum_guard:relation_val[now] -= muti_val * unit_valrelation_val[now] -= muti_val * (sum_guard >> 3)relation_val[1 - now] -= muti_val * ((sum_attack - max_attack) >> 3)# 如果是n换n,攻击方与保护方数量相同并且攻击者子力小于被攻击者子力与保护者子力之和再减去保护者中最大子力,则对方可能以n子换n子elif num_guarded == num_attacked and sum_attack < cc.base_val[now_chess.chess_type] + sum_guard - max_guard:relation_val[now] -= muti_val * unit_valrelation_val[now] -= muti_val * ((sum_guard - max_guard) >> 3)relation_val[1 - now] -= sum_attack >> 3# print('-------------------------')# print(base_val[0], pos_val[0], mobile_val[0], relation_val[0])# print(base_val[1], pos_val[1], mobile_val[1], relation_val[1])my_max_val = base_val[0] + pos_val[0] + mobile_val[0] + relation_val[0]my_min_val = base_val[1] + pos_val[1] + mobile_val[1] + relation_val[1]if who == 0:return my_max_val - my_min_valelse:return my_min_val - my_max_valdef init_relation_list(self):res_list = []for i in range(9):res_list.append([])for j in range(10):res_list[i].append(Relation())return res_listdef is_game_over(self, who):  # 判断游戏是否结束for i in range(9):for j in range(10):if self.board.board[i][j].chess_type == cc.jiang:if self.board.board[i][j].belong == who:return Falsereturn Truedef move_to(self, step, flag=False):  # 移动棋子belong = self.board.board[step.to_x][step.to_y].belongchess_type = self.board.board[step.to_x][step.to_y].chess_typetemp = mc.chess(belong, chess_type)# if flag:#     self.board.print_board()#     print(self.board.board[step.to_x][step.to_y].chess_type)self.board.board[step.to_x][step.to_y].chess_type = self.board.board[step.from_x][step.from_y].chess_type# if flag:#     print(self.board.board[step.from_x][step.from_y].chess_type)#     print(self.board.board[step.to_x][step.to_y].chess_type)#     print(step.to_x, step.to_y)self.board.board[step.to_x][step.to_y].belong = self.board.board[step.from_x][step.from_y].belongself.board.board[step.from_x][step.from_y].chess_type = cc.kongself.board.board[step.from_x][step.from_y].belong = -1return tempdef undo_move(self, step, chess):  # 恢复棋子self.board.board[step.from_x][step.from_y].belong = self.board.board[step.to_x][step.to_y].belongself.board.board[step.from_x][step.from_y].chess_type = self.board.board[step.to_x][step.to_y].chess_typeself.board.board[step.to_x][step.to_y].belong = chess.belongself.board.board[step.to_x][step.to_y].chess_type = chess.chess_typeif __name__ == "__main__":game = my_game()game.board.print_board()while (True):from_x = int(input())from_y = int(input())to_x = int(input())to_y = int(input())s = mc.step(from_x, from_y, to_x, to_y)game.board.print_board()game.alpha_beta(game.max_depth, cc.min_val, cc.max_val)print(game.best_move)game.move_to(game.best_move)game.move_to(s)game.board.print_board()

3、参考文献

以下的代码冗长且复杂,文件多,我对他们的代码进行了注释并简化了不少,所以下载我的就行

中国象棋python实现(拥有完整源代码) Alpha-beta剪枝+GUI+历史启发式+有普通人棋力

人工智能—Alpha-Beta剪枝(中国象棋)

python_pygame_alpha-beta剪枝算法_玩中国象棋相关推荐

  1. linux终端 中国象棋,在Deepin系统下安装Xboard并使用它玩中国象棋

    本文介绍在Deepin系统下安装Xboard的命令,并通过xboard @xq命令进入到中国象棋模式,有喜爱中国象棋的网友又可以多一种途径了,当然,也可以玩国际象棋. 前言 Xboard/WinBoa ...

  2. 多少秒算长镜头_下中国象棋,能算多少步才算高手?

    下象棋,你能算多少步?这是一个让初学者很困扰,也很感兴趣的话题. 很多象棋爱好者说:我最多看2步,我觉得能看5步以上的,就是超级高手高手高高手了. 但一代象棋宗师.14届全国冠军胡荣华的看法则颇有&q ...

  3. alpha beta 剪枝算法

    摘自wikipedia alpha-β修剪的好处在于可以消除搜索树的分支.这样,搜索时间可以限制在"更有希望"的子​​树中,并且可以在同一时间执行更深入的搜索.该算法和极小化极大算 ...

  4. 五子棋AI算法第三篇-Alpha Beta剪枝

    剪枝是必须的 五子棋AI教程第二版发布啦,地址:https://github.com/lihongxun945/myblog/labels/%E4%BA%94%E5%AD%90%E6%A3%8BAI% ...

  5. alpha-beta剪枝五子棋c语言,五子棋AI算法第三篇-Alpha Beta剪枝

    剪枝是必须的 上一篇讲了极大极小值搜索,其实单纯的极大极小值搜索算法并没有实际意义. 可以做一个简单的计算,平均一步考虑 50 种可能性的话,思考到第四层,那么搜索的节点数就是 50^4 = 6250 ...

  6. 五子棋AI算法-Alpha Beta剪枝

    上一篇讲了极大极小值搜索,其实单纯的极大极小值搜索算法并没有实际意义. 可以做一个简单的计算,平均一步考虑 50 种可能性的话,思考到第四层,那么搜索的节点数就是 50^4 = 6250000,在我的 ...

  7. 中国象棋通用引擎协议 UCCI

    概述 中国象棋通用引擎协议 (Universal Chinese Chess Protocol,简称UCCI),是一种象棋界面和象棋引擎之间的基于文本的通讯协议. 规范通用引擎协议 UCCI 协议,为 ...

  8. Alpha-Beta剪枝算法在直棋中的运用

    游戏说明 详见本人的项目描述页面:https://gitee.com/liuweilhy/NineChess/blob/master/Readme.md 我做了个简单的GUI如下图. 点击这里可以下载 ...

  9. linux上的中国象棋游戏下载,中国象棋下载_中国象棋最新下载_玩一玩游戏

    中国象棋是起源于中国,的一种棋类游戏,属于两个人之间的对抗,在中国有着悠久的历史.由于它的器皿简单,趣味性强,它已经成为一种非常受欢迎的棋类活动. 中国象棋是中华民族的文化瑰宝,历史悠久,趣味性强,基 ...

最新文章

  1. android 高通平台有前途吗,华为鸿蒙计划要适配高通平台了,可以告别安卓搭载鸿蒙OS了?...
  2. 直播回顾|结构光编码与三维重建技术
  3. mysql中文查询问题
  4. 人口问题,怎样的生育率才能保持正常的世代更替?
  5. PyCharm----快捷键
  6. Data URI scheme 在 html 中嵌入小图片
  7. 也谈子网划分和子网通信
  8. LeetCode 1031. 两个非重叠子数组的最大和(一次遍历,要复习)*
  9. c# combobox集合数据不显示_Excel也能玩转百万数据
  10. java环境变量都是什么意思_Java环境变量,真的还有必要配吗?
  11. 单件模式与业务逻辑服务层封装
  12. 【求助】如何从 Spark 的 DataFrame 中取出具体某一行?我自己的一些思考
  13. php的数据结构有哪些,PHP数据结构有几种
  14. jquery和Js的区别和基础操作
  15. C#创建Windows窗体应用程序实例8【通用对话框】
  16. 方向导数,偏导数,梯度
  17. 首届Filecoin矿工大会会议重点
  18. 使用yguard混淆,名字出现超长字符 map=“ooooooooooooooo”
  19. Golang入门之——文件锁操作flock
  20. stm32驱动Lora串口模块

热门文章

  1. 15.A Syntactic Neural Model for General-Purpose Code Generation
  2. Mac启动台缺少已下载应用软件图标
  3. 短信网关接口开发技术
  4. 华为笔试题库之较难--难度
  5. 马上6等待服务器响应,解决网页响应慢,等待时间过长,waiting(TTFB)时间过长...
  6. 本地网络环境测试工具,很不错的工具
  7. ie浏览器java不弹窗_解决IE屏蔽Java Applet问题的方法 .
  8. iOS-----GitHub上比较齐全的iOS 工具和App
  9. z390 m.2 接口插上sata 硬盘后,机械硬盘不识别;HDD 硬盘不识别;z390 m.2和 SATA 硬盘安装组合;
  10. 微信小程序二手交易系统ssm框架——计算机毕业设计