实战 Flutter 象棋从零到上架
專欄亮點
- 基于真實項目「棋路」的開發歷程形成專欄,不是市面上的各種「HelloWorld」;
- 專欄內容包含其中的每一和代碼,都得到了兩次驗證,跟隨我們的專欄,定能達成目標;
- 真實項目環境中遇到的大量問題,專欄中都給出了實用的解決方案;
- 對開源的 C++ 引擎的包裝和混編,有大量市面上找不到的經驗和方法。
為什么應盡早學習 Flutter
這個世界已經有太多的框架,我們為什么需要學習一種新的?
簡單點來回答這個問題 —— 效率!
- 跨平臺的解決方案,做一套應用,可以在 iOS、Android、WEB、MacOS、Windows 多端運行
- 基于 Dart 語言建立的原生繪圖性能,超越 Hybrid 方案和其它 JS 翻譯方案;
- 調試期間的熱加載,不需要每次都編譯代碼,能極大地提升開始發效率;
- 更先進的界面布局理念,上手后做同樣的界面花費的代價低于 iOS 或是 Android;
掌握前沿的技術,順應技術演進的趨勢,抱緊 google 的大腿,現在就是上路的時候了。
現在學習 Flutter 的常見痛苦
- 看了官方的文檔和教程,感覺是大師的理論堆砌,與手上的項目無法關聯起來;
- 中文的 Flutter 教程也真不少,但都是一個一個的 Demo,沒有深入的應用了討論;
- 自己嘗試使用 Flutter 開發時,遇到一些坑點時,無認幫忙,各種教程從未提到這些復雜場面;
我們的專欄中完整跟進了「棋路」象棋游戲在開發中遇到的各種問題,嘗試解決問題的方式不限于 Flutter 或 Dart,而是實用為王。從真實項目的,你能得到語言或框架以外的經驗和知識。
專欄組織
專欄涉及到的主要技術
以下的專欄中涉及到的主要知識點,以及推薦的學習資源:
Dart 語言知識
Dart 語言容易學習和使用,如果你學習過 C++ 或是 Java,學習 Dart 將非常容易和快捷。可以試看 GitChat 專欄《Dart 入門實踐》,你能在幾個小時內掌握 Dart 語言的精義。
Flutter 開發技術
如果你有過 iOS 或 Android 的開發經驗,亦或是你有 Ionic 或 Web 開發經驗,則完全不用擔心 Flutter 的入門問題。即使什么開發經驗都沒有,Dart 的入門也是容易的。使用中文的 Flutter 官方文檔,是 Flutter 入門的好辦法。
iOS 和 Android 開發基礎知識
我們要做的是跨平臺的游戲 App,對 iOS 和 Android 開發有基本的了解是很有幫助的,但這并不是這個專欄的前提。我們的專欄中除了單機引擎部分調用了 C++ 原生引擎、需要在 iOS 和 Android 平臺上進行少量混合開發外,其它的內容都是在 Flutter 環境下實現的。即使你沒有 iOS 和 Android 開發基礎,跟著我們的專欄指示,你也能完成全部的開發任務。
如果你想要系統地學習 iOS 開發技術,那么以下這些鏈接將給你絕佳的入門引導:
Swift5 語言簡介
Swift 語言 Getting Start
Start Developing iOS Apps (Swift)
如果你有志于系統地學習 Android 開發技術,那么以下這鏈接你也千萬別錯過:
百度搜索:《Thinking in Java》電子版
構建你的第一個 Android 應用
Android 開發者指南
Android 官方開發示例
Android 開發技術
C/C++開發技術
專欄中將使用 C++ 語言實現的人機對戰引擎來做電腦端的大腦,如果有一定的 C++ 基礎,將有利于你得更好地理解象棋對戰引擎的實現原理。這當然不是學習這門專欄的前提。即使沒有接觸過 C/C++ 語言,你不會阻礙你順暢地學習我們的專欄。
百度搜索:《Thinking in C++》電子版
菜鳥 C++基礎教程
Nodejs / Koa 開發技術
Nodejs 技術棧非常流行,其生態也是枝繁葉茂。
我們的專欄并不要求你掌握 Nodejs 技術棧的知識,但 Nodejs 學習和應用極簡單明快,是我技術學習過程中最愉快的一段經歷了。我推薦大家課后學習 Nodejs 技術;作為一個現代的開發人員,不應該對如此活躍的一個生態一無所知。
Nodejs 和 Koa 的學習,建議直接去官網:Koa 的首頁文章對你理解和入門 Koa 極有幫助。
不必擔心自己尚未掌握這些技術點,我們專欄的每一個環節都呈現了可執行的代碼和指令,這些代碼都經過了作者的至少兩輪從頭到尾的驗證。
只需要跟著專欄的腳步,一步一步地往下走,在實踐中去做、去體會,理論正是來自于實踐的。
實踐中你將收獲
跟隨我們的教程,實現中國象棋的游戲過程,你將學習到以下知識點:
Flutter 基礎知識
- 組件及布局知識
- 手勢檢測
- Http 通信
- Canvas 繪制
- Method Channel 與原生應用通信
- 動畫技術要領
- 音樂、音效
- 用戶本地配置解決方案
- 多種設備屏幕適配
象棋軟件開發知識
- 象棋的基本規則
- 象棋著法枚舉和有效性判斷
- 長捉和勝負檢測
- FEN 局面表示
- UCCI 引擎通信協議
- XQF 象棋棋譜格式的解析
Native 開發知識
- 在 iOS 和 Android 中訪問 Flutter 資源包
- iOS 中 Object C 與 C++ 的混合開發
- iOS 的多線程通信
- Android 中 Java 與 C++ 通過 JNI 協同
- Android 的多線程通信
產品設計知識
- 用戶需求提煉
- 交互設計
一個完整的產品涉及到的細節比較多,有些特定場景到我們遇到時再和大家分解。
目標讀者
現實當中,每一個真實產品的開發過程幾乎不可能只使用一種技術、甚至一套技術棧,正是由于這個原因,許多開發人員學習了某種語言的一系列專欄、完成一系列專欄中的 demo 后,并不能實際完成公司或項目組交給的真實項目任務,這正是純理論專欄的短板!
我們的專欄反映了真實項目的眾多細節,中間的銜接與各種技術的綜合運用來自于長期的項目實踐,接近并學習這些知識,能快速地提升你獨立完成真實項目任務的能力。
如果你是開發界的新兵,學習我們的專欄將助你在實際中學習 Dart/Flutter 綜合應用能力,關鍵能提升你對互聯網產品的整個生命周期的理解。
如果你已經是經驗豐富的開發老兵了,跟隨這個專欄你除了能學習到一些具體問題的解決方法外,還將學習到解決問題的更多思路、各種設計模式與開發的流程。
如果你是學生,將會發現這個專欄和你以前讀到的各種課本完全不同,它實用而不教條,在帶給你難得的項目實踐經驗的同時,助打開廣闊的技術視野。
關于作者
賀照云,曾就職于騰訊、聯想軟件、360;十年開發經驗、十年產品策劃經驗; 熟悉 C++、Java、JS、Swift、Dart、Groovy 等多種語言;熟悉 J2EE/Nodes/Android/iOS/Windows 等多種開發平臺;
訂閱須知
- 本專欄為圖文內容,共計 24 篇。
- 本專欄為虛擬產品,一經付費概不退款,敬請諒解。
- 本專欄可在 GitChat 服務號、App 及網頁端 gitbook.cn 上購買,一端購買,多端閱讀。
訂閱福利
- 訂購本專欄可獲得專屬海報(在 GitChat 服務號領取),分享專屬海報每成功邀請一位好友購買,即可獲得 25% 的返現獎勵,多邀多得,上不封頂,立即提現。
- 提現流程:在 GitChat 服務號中點擊「我-我的邀請-提現」。
- 購買本專欄后,服務號會自動彈出入群二維碼和暗號。如果你沒有收到那就先關注微信服務號「GitChat」,或者加我們的小助手「Linmicc」咨詢。
- 點擊這里跳轉至《第 3 篇》翻閱至文末獲得入群口令。
課程內容
中國象棋通用引擎協議 UCCI
概述
中國象棋通用引擎協議 (Universal Chinese Chess Protocol,簡稱UCCI),是一種象棋界面和象棋引擎之間的基于文本的通訊協議。
規范通用引擎協議 UCCI 協議,為棋軟的 AI 引擎與界面分享提供標準接口,一些團隊可以實現優美的界面,而另一些團隊可以關注于 AI 引擎算法提升。
中國象棋的軟件理論主要參考了國際象棋,通用引擎協議也是這樣。UCCI 參考國際象棋的 UCI 來制定的。
通訊方法
通常情況下,引擎程序以獨立進程方式運行,以標準輸入輸出與界面程序進行通信。
獨立進程運行的情況下,象棋軟件使用輸入輸出管道方式與作為子進程的引擎程序進行通信,通信內容為文本。/Users/linmi/Documents/Work/GitChat/專欄/照云/flutter 實戰:中國象棋引擎也可以象棋程序的線程方式運行,象棋軟件和引擎運行于同一個內存空間,可以使用更靈活的方式進行通信。
象棋程序與引擎之間的通信過程一般是這樣的:
局面和著法表示
局面表示
象棋程序以 position 指令告知引擎局面信息。局面信息以 FEN 方式標記,一個典型的局面指令:
position fen rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1為了讓引擎自動判斷禁手(重復等),可以在 position 指令中分兩部分反應局面信息,一部分是上一次吃子(或開局)后的局面,另一部分是上一次吃子后的招法列表。
position fen rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1Case 2 - 紅方走出了炮二平五,請求引擎為黑方出著:無咋子局面,使用開局局面,有一步著法:
position fen rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1 moves h2e2Case 3 - 黑方炮8平5,請引擎為紅方出著:無吃子過程,有兩步著法:
position fen rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1 moves h2e2 h7e7Case 4 - 紅方炮五進四,請引擎為黑方出著:前一步紅方吃子,局面變化最最近吃子局面,無著法列表:
position fen rnbakabnr/9/1c2c4/p1p1C1p1p/9/9/P1P1P1P1P/1C7/9/RNBAKABNR b - - 0 2Case 5 - 黑方走出士4進5,請引擎為紅方出著,使用上一個咋子局面,著法列表中是上一步黑方「士4進5」:
position fen rnbakabnr/9/1c2c4/p1p1C1p1p/9/9/P1P1P1P1P/1C7/9/RNBAKABNR b - - 0 2 moves d9e8著法表示
象棋應用和引擎程序之間對著法的表示使用 ICCS 格式。
ICCS 格式用 4 個字符表示一步著法的,例如 b0c2 :
- ICCS 著法基于左下角坐標系
- 用 a ~ i 表示從左到右的 9 列
- 用 0 ~ 9 表示從下到上 10 行
舉個例子,引擎返回著法 b0c2,表示將第2列第1行的棋子移動到第3列第3行。
指令和反饋
指令
ucci這是引擎啟動后,界面需要給引擎發送的第一條指令,通知引擎現在使用的協議是UCCI。
響應1
id {name | copyright | author | user} <信息>返回引擎的版本號、版權、作者和授權用戶,例如:
id name ElephantEye 1.6 Betaid copyright 2004-2006 www.xqbase.comid author Morning Yellowid user ElephantEye Test Team響應2
option <選項> type <類型> [min <最小值>] [max <最大值>] [var <可選項> [var <可選項> [...]]] [default <默認值>]顯示引擎所支持的選項,UCCI 引擎支持以下選項:
- usemillisec true,通知界面采用毫秒模式
- batch false,批處理模式,默認是關閉的;
- debug false,調試模式,默認是關閉的;
- ponder false,是否使用后臺思考的時間策略,默認是關閉的;
- usebook true,是否使用開局庫的著法,默認是啟用的;
- useegtb true,是否使用殘局庫,默認是啟用的;
- bookfiles <bookfile-name>,設定開局庫文件的名稱,可指定多個開局庫文件,用分號「;」隔開;
- egtbpaths <bookfile-name>,設定殘局庫路徑的名稱,和 bookfiles 類似;
- evalapi <lib-name>,設定局面評價API函數庫文件的名稱,和 bookfiles 類似,但只能是一個文件;
- hashsize <number>,以MB為單位規定Hash表的大小,0表示讓引擎自動分配Hash表;
- threads <number>,支持多處理器并行運算(SMP)的引擎可指定線程數(即最多可運行在多少處理器上),0表示讓引擎自動分配線程數;
- idle <none|small|medium|large>,設定處理器的空閑狀態,通常有none(滿負荷)、small(高負荷)、medium(中負荷)、large(低符合)四種選項,引擎默認總是以滿負荷狀態運行的;
- promotion false,是否允許仕(士)相(象)升變成兵(卒),這是一種中國象棋的改良玩法,默認是不允許的;
- pruning <none|small|medium|large>,設定裁剪程度,裁剪越多則引擎的搜索速度越快,但搜索結果不準確的可能性越大;
- knowledge <none|small|medium|large>,設定知識大小,通常知識量越多則程序的靜態局面評價越準確,但的運算速度會變慢;
- randomness <none|small|medium|large>,設定隨機性系數,一般都設為none,以保證引擎走出它認為最好的著法,但為了增強走棋的趣味性,可以把這個參數調高;
- style <solid|normal|risky>,設定下棋的風格;
- newgame,設置新局或新的局面,引擎收到該指令時,可以執行導入開局庫、清空Hash表等操作;
響應3
ucciok引導狀態的反饋,此后引擎進入空閑狀態。
指令
isready檢測引擎是否處于就緒狀態
響應
readyok表明引擎處于就緒狀態。
指令
setoption <選項> [<值>]設置引擎參數,這些參數都應該是前述 ucci 指令的 option 反饋的參數,例如:
setoption usebook false,不讓引擎使用開局庫; setoption selectivity large,把選擇性設成最大; setoption style risky,指定冒進的走棋風格; setoption loadbook,初始化開局庫。
指令
position {fen <FEN串> | startpos} [moves <后續著法列表>]設置局面,用 fen 來指定 FEN 格式串,moves 后面跟的是隨后走過的著法。startpos表示開始局面,它等價于 rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1
指令
banmoves <禁止著法列表>為當前局面設置禁手,以解決引擎無法處理的長打問題
指令
go [ponder | draw] <思考模式>要求引擎根據 position 指令設定的棋盤來思考,各選項為思考方式,有三種模式可供選擇:
- depth <深度> | infinite:限定搜索深度,infinite 表示無限制思考(直到找到殺棋或用 stop 指令中止)。如果深度設定為 0,那么引擎可以只列出當前局面靜態評價的分數,并且反饋 nobestmove。
- nodes <結點數>:限定搜索結點數。
- time <時間> [movestogo <剩余步數> | increment <每步加時>] [opptime <對方時間> [oppmovestogo <對方剩余步數> | oppincrement <對方每步加時>]]:限定時間,時間單位毫秒
- movestogo適用于時段制
- increment適用于加時制
- opptime、oppmovestogo 和 oppincrement 可以讓界面把對方的用時情況告訴引擎。
- 如果指定 ponder 選項,則引擎思考時時鐘不走,直到接受到 ponderhit 指令后才計時,該選項用于后臺思考,它只對限定時間的思考模式有效。
- 指定 draw 選項表示向引擎提和,引擎以 bestmove 提供的選項作為反饋,參閱 bestmove 指令。
- ponder 和 draw 選項不能同時使用,如果界面向正在后臺思考中的引擎求和,則使用 ponderhit draw 指令。
響應1
info <思考信息>顯示引擎思考信息,通常有以下幾種信息:
- time <已花費的時間> nodes <已搜索的結點數>
- depth <當前搜索深度> [score <分值> pv <主要變例>]:輸出引擎思考到的深度及其思考路線和好壞
- currmove <當前搜索著法>:輸出引擎正在思考的著法
- message <提示信息>:輸出引擎要直接告訴用戶的信息
中間指令
ponderhit [draw]思考過程中的指令,告訴引擎后臺思考命中,現在轉入正常思考模式(引擎繼續處于思考狀態,此時go指令設定的時限開始起作用)。draw 選項表示向引擎提和,引擎以 bestmove 提供的選項作為反饋。
中間指令
stop中止引擎的思考。注意:發出該指令并不意味著引擎將立即回到空閑狀態,而是要等到引擎反饋bestmove或nobestmove后才表示回到空閑狀態。
響應2-1
bestmove <最佳著法> [ponder <后臺思考的猜測著法>] [draw | resign]思考結果反饋,以及猜測在這個著法后對手會有怎樣的應對。
通常,最佳著法是思考路線、中的第一個著法,而后臺思考的猜測著法則是第二個著法。在對手尚未落子時,可以根據該著法來設定局面,并作后臺思考。當對手走出的著法和后臺思考的猜測著法吻合時,稱為“后臺思考命中”。
draw 選項表示引擎提和或者接受界面向引擎發送的提和請求
resign 選項表示引擎認輸。
響應2-2
nobestmove反饋思考結果,但引擎一步著法也沒計算,表示當前局面是死局面,或者接收到諸如 go depth 0 等只讓引擎給出靜態局面評價的指令。
指令
quit讓引擎退出運轉。
響應
bye接收到 quit 指令后的反饋
電腦象棋聯賽中的 UCCI
電腦象棋聯賽使用 UCCI 引擎,參賽引擎必須能夠識別并正確處理以下的指令:
- ucci;
- position fen … [moves …];
- banmoves …;
- go [draw] time … increment … [opptime … oppincrement …];
- quit。
參賽引擎必須能夠反饋的信息有:
- ucciok;
- bestmove … [draw | resign]。
為了更好地讓引擎適應模擬器,引擎最好能夠實現以下功能:
- 支持毫秒制,即啟動時有 option usemillisec 的反饋,能夠識別并處理 setoption usemillisec true 的指令
- 支持認輸和提和,即當引擎覺得沒有機會獲勝時,可以用 bestmove … draw 提和或接受提和
- 支持 stop 指令
另外,識別 setoption 指令不是必須的,但在聯賽中也會有用,例如用 setoption bookfiles …來導入開局庫。
前言:在學習本專欄之前
動手之前要做的事:梳理開發環境
先畫它一個棋盤:繪制棋盤 Board
戰場怎能缺少兵卒:棋子的繪制
支持行棋動作:處理移動棋子和吃子邏輯
實現游戲骨架:添加基本的界面元素
挑戰云主機戰:學習使用云端服器象棋云庫
確保著法合規:象棋通用規則解析
檢查對戰結果:實現勝負的邏輯
提升體驗:為游戲添加聲色
實現真正的「人機」對戰:引入三方 AI 引擎
規劃引擎工作模式
封裝 iOS 原生引擎
封裝 Androd 原生引擎
記譜以提供悔棋功能
超神能力:云庫局面分析
為軟件添加全網排行榜
用 Koa2 實現后臺服務
添加游戲設置
為上架作準備
后記:作者有話說
中國象棋游戲規范
FEN 局面表示
閱讀全文: http://gitbook.cn/gitchat/column/5e9d67352b34772795873df4
總結
以上是生活随笔為你收集整理的实战 Flutter 象棋从零到上架的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 世界最早投入运行的计算机网络是,世界最早
- 下一篇: android 官方说明文档,Andro