diff --git a/README.md b/README.md index 1cf5d86..bedd2b7 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,118 @@ -# harmless +# Harmless 象棋引擎 -A chinese chess engine +一个中国象棋(Chinese Chess)引擎,包含 C 语言编写的 AI 引擎和 Python 编写的图形界面。 -## INSTALL +## 功能特性 -### GNU/Linux and Mac OS X User +- 🎮 **人机对战**:与 AI 引擎对弈 +- 🌐 **网络对战**:支持双人网络对战 +- 🔊 **音效支持**:移动、吃子、将军音效 +- 📖 **开局库**:内置开局数据库 (BOOK.DAT) +- 🎯 **UCCI 协议**:引擎支持 UCCI (Universal Chinese Chess Interface) 协议 -> require +## 项目结构 -* `python-2.7.x`: -* `pygame-1.9.x`: +``` +harmless/ +├── src/ # C 语言象棋引擎源码 +│ ├── harmless.c # 主程序入口 +│ ├── search.c # 搜索算法 +│ ├── evaluate.c # 局面评估 +│ ├── genmoves.c # 走法生成 +│ ├── position.c # 棋盘位置处理 +│ ├── hash.c # 哈希表 +│ ├── openbook.c # 开局库 +│ └── ucci.c # UCCI 协议实现 +├── pycchess/ # Python 图形界面 +│ ├── cchess.py # 主程序 +│ ├── chessboard.py # 棋盘逻辑 +│ ├── chessman.py # 棋子逻辑 +│ ├── chessnet.py # 网络对战 +│ ├── image/ # 棋子图片资源 +│ └── sounds/ # 音效文件 +├── Makefile # 构建脚本 +└── README.md +``` + +## 安装说明 + +### 环境要求 + +- **GCC**: C 编译器 +- **Python 2.7.x**: +- **Pygame 1.9.x**: + +### GNU/Linux 和 macOS + +```bash +# 克隆仓库 +git clone https://github.com/timebug/harmless.git +cd harmless + +# 编译引擎并安装 +make && make install + +# 运行游戏 +cd pycchess && python cchess.py +``` + +#### macOS 安装 Pygame 提示 + +参考: -Hint: install pygame on OS X Lion +### Windows - +1. 访问 +2. 下载 `pycchess-win32-*.zip` 并解压 +3. 运行 `cchess.exe` -> run +## 使用说明 +### 游戏模式 + +**人机对战(默认)**: +```bash +cd pycchess && python cchess.py ``` -$ git clone git://github.com/timebug/harmless.git -$ make && make install -$ cd pycchess && python cchess.py + +**网络对战**: +```bash +# 红方 +python cchess.py -nr + +# 黑方 +python cchess.py -nb ``` -### Windows User +### 键盘快捷键 + +| 按键 | 功能 | +|------|------| +| `Space` | 开始新游戏 | + +### 游戏操作 + +- 鼠标点击选择棋子 +- 再次点击目标位置移动棋子 + +## 技术实现 + +### 引擎特性 + +- **Alpha-Beta 剪枝搜索** +- **置换表 (Transposition Table)** +- **走法排序优化** +- **开局库支持** +- **局面评估函数** + +### UCCI 协议 + +引擎支持 UCCI 协议,可与其他支持 UCCI 的界面程序配合使用。 + +## 许可证 -1. Access -2. Download `pycchess-win32-*.zip` then unzip it -3. Run `cchess.exe` +本项目采用 GNU General Public License v3.0 许可证。 -## KEYBOARD SHORTCUTS +## 致谢 -* `space`: new game +- pycchess UI - Copyright (C) 2011 - 2015 timebug diff --git a/hello.txt b/hello.txt new file mode 100644 index 0000000..ce01362 --- /dev/null +++ b/hello.txt @@ -0,0 +1 @@ +hello diff --git a/src/base.h b/src/base.h deleted file mode 100644 index 522cf18..0000000 --- a/src/base.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef BASE_H -#define BASE_H - -#include - -#define RED 0 -#define BLACK 1 - -#define KING 0 -#define ADVISOR 1 -#define BISHOP 2 -#define KNIGHT 3 -#define ROOK 4 -#define CANNON 5 -#define PAWN 6 - -#define INFINITE_ 20000 -/* 最大搜索棋局深度 */ -#define MAX_SEARCH_DEPTH 50 - -typedef unsigned char BYTE; -typedef unsigned long INT32_; -typedef unsigned long long INT64_; - -typedef struct { - BYTE from; - BYTE to; - unsigned short capture; -} move; - -extern move NULL_MOVE; - -#define DEBUG_LOG -/* 日志文件描述符 */ -extern FILE *logfile; - -#endif diff --git a/src/hash.c b/src/hash.c deleted file mode 100644 index b8a4bf0..0000000 --- a/src/hash.c +++ /dev/null @@ -1,105 +0,0 @@ -#include -#include -#include - -#include "hash.h" - -INT32_ zobrist_player; -INT64_ zobrist_player_check; -INT32_ zobrist_table[14][256]; -INT64_ zobrist_table_check[14][256]; - -INT32_ zobrist_key; -INT64_ zobrist_key_check; -INT32_ hash_mask; -hash_node *hash_table; - -INT32_ rand32() -{ - return rand() ^ ((INT32_)rand() << 15) ^ ((INT32_)rand() << 30); -} - -static INT64_ rand64() -{ - return rand() ^ ((INT64_)rand() << 15) ^ ((INT64_)rand() << 30) ^ - ((INT64_)rand() << 45) ^ ((INT64_)rand() << 60); -} - -static void init_zobrist() -{ - int i, j; - srand(time(NULL)); - - zobrist_player = rand32(); - for (i = 0; i < 14; i++) { - for (j = 0; j < 256; j++) { - zobrist_table[i][j] = rand32(); - } - } - - zobrist_player_check = rand64(); - for (i = 0; i < 14; i++) { - for (j = 0; j < 256; j++) { - zobrist_table_check[i][j] = rand64(); - } - } -} - -void reset_hash_table() -{ - memset(hash_table, 0, HASH_TABLE_SIZE * sizeof(hash_node)); -} - -void new_hash_table() -{ - init_zobrist(); - - hash_mask = HASH_TABLE_SIZE - 1; - hash_table = (hash_node *)malloc(HASH_TABLE_SIZE * sizeof(hash_node)); - reset_hash_table(); -} - -void del_hash_table() -{ - if (hash_table) - free(hash_table); -} - -void save_hash_table(int value, int depth, data_type type, move mv) -{ - int add = zobrist_key & hash_mask; - hash_node *pnode = &hash_table[add]; - - pnode->value = value; - pnode->checksum = zobrist_key_check; - pnode->depth = depth; - pnode->type = type; - pnode->goodmove = mv; -} - -int read_hash_table(int depth, int alpha, int beta, move *mv) -{ - int add = zobrist_key & hash_mask; - hash_node *pnode = &hash_table[add]; - - if (pnode->depth >= depth && - pnode->checksum == zobrist_key_check) { - - /* 确切值 */ - if (pnode->type == HASH_EXACT) - return pnode->value; - - /* 上边界 */ - if (pnode->type == HASH_ALPHA && pnode->value <= alpha) - return pnode->value; - - /* 下边界 */ - if (pnode->type == HASH_BETA && pnode->value >= beta) - return pnode->value; - - (*mv) = pnode->goodmove; - } - - /* 没有命中,返回无效标志 */ - return NOVALUE; -}