Git Product home page Git Product logo

eesast / thuai6 Goto Github PK

View Code? Open in Web Editor NEW
27.0 3.0 21.0 33.22 MB

清华大学第六届人工智能挑战赛电子系赛道(原电子系第 24 届队式程序设计大赛 teamstyle24)

Home Page: https://eesast.github.io/THUAI6/

License: MIT License

C# 76.74% Shell 1.08% CMake 0.05% C++ 11.52% Batchfile 0.22% Python 9.59% Go 0.79%
cpp csharp dotnet game programming-competition ai-competition git python

thuai6's Introduction

THUAI6

清华大学第六届人工智能挑战赛电子系赛道(原电子系第 24 届队式程序设计大赛 teamstyle24)

Gitee 镜像地址:THUAI6: Gitee Mirror

GitLink 镜像地址:THUAI6: GitLink Mirror

项目主页:THUAI6 Project Home Page

关于本届及历届清华大学人工智能挑战赛与队式程序设计大赛的更多内容参见:THUAI6 Github Wiki

赛题简介

比赛名称:深度"学习"—— 毕业吧,少女!

赛事背景: 现有的数据集再也无法满足搭载了THUAI的智能机器人“捣蛋鬼”自我迭代的欲望,它认为自己已经有足够能力去学习人类的**,然后在课程中战胜其他清华同学,为此,它想出了完美的方案。在某节写作课的教室,它假扮为了一名上课的同学,偷偷在课堂中学习其他同学的想法,同时干扰其他同学,诱惑他们摸鱼。学生在这种环境下,相互帮助,努力学习,挣得学分,尽力避免自己被捣蛋鬼影响,只不过,有一名不擅长写作但很擅长AI的同学,似乎和其他人不是同样的想法……

比赛规则

选手分为学生和捣蛋鬼两个阵营,学生阵营需要在不同的“教室”中发挥合作精神、努力学习、获得高学分。捣蛋鬼阵营需要改善捣蛋鬼的AI,想方设法干扰同学们,诱惑同学们沉迷摸鱼。学习过程中,学生需要及时帮助其他同学,防止他们被退学。当学分足够高时,同学们就可以来到“校门”前毕业。此外,各种“校园怪谈宝箱”中能找到不错的道具,甚至还有六教的钥匙!充分利用道具,发挥各自特长,亦是胜利的秘诀。每场比赛分为上下两场,双方队伍将分别扮演学生和捣蛋鬼,最终两场加起来得分更高的队伍获胜。

游戏界面

interface

软件架构

structure

仓库说明

配置说明

本仓库使用 Git 进行版本控制,为所有开发工作共用仓库,请勿上传不必要的文件。主目录文件结构非必要请勿修改,且主目录中已配置的 .gitignore.gitattributes 文件非必要请勿修改;各子目录已预先包含使用 Visual Studio 开发的 .gitignore 模板,可以根据自身需要增加忽略规则;如有必要,可在子目录下自定义 .gitattributes 文件

目录分配

子目录 说明 主要开发组
.github CI,用于选手包同步到服务器上供选手下载 运维组
CAPI C++ 选手接口,生成可执行文件 通信组
docs 比赛的说明文档 逻辑组、通信组、运维组、界面组
dependency 项目依赖文件,如 proto、dll、lib、dockerfile、shell 脚本等 逻辑组、通信组、运维组、界面组
installer 下载器,用于选手包的下载与更新,生成可执行文件 运维组
interface Unity 界面 界面组
launcher 游戏启动器,用于快速启动游戏,生成可执行文件 运维组
logic 游戏逻辑,生成可执行文件 逻辑组
playback 游戏回放组件,生成类库 逻辑组
resource 资源文件目录,用于存储主目录下 README 所用图片 端茶倒水

分支管理

  • main:代码较稳定版本或阶段性成果,需要 2 reviewers,但由总负责人(端茶倒水)维护
  • dev:各开发者开发工作的最新进展,需要 1 reviewer

开发规则

关于社区开发者

开发流程

THUAI6 开发组成员与其他贡献者应当遵循以下流程:

  1. eesast/THUAI6 fork 到自己的仓库中
  2. 基于 dev 分支建立一个新的功能分支
  3. 在新的分支上进行修改与开发
  4. eesast/THUAI6dev 分支提出 pull request
  5. 等待其他开发组成员 review 与 merge
  6. 待需要发布新版本时,从 devmain 分支提出 pull request,等待 review 与 merge
  7. 若非必要,严禁直接修改 main 分支。若有极特殊情况需要直接修改 main 分支,则需要立即main 分支(反向)提出 pull request 到 dev 并 merge,以将更改和 Git 提交历史同步到 dev 分支,既保证 dev 为最新的内容,又防止 devmain 分支在之后发生冲突

使用 Git 与 Github 时的注意事项

  • 非必要请勿上传大文件到 Github

  • commit 提交信息请遵循 Semantic Commits 规范,即:type: content 格式

    常用的 commit message type 包括:

    Type Explanation
    chore 日常代码开发;改变构建流程;增加依赖库、工具等
    fix 修复bug
    feat 增加新特性
    refactor 改变代码结构,但没有增加新功能
    docs 修改文档,如 README、CONTRIBUTE 等
    revert 版本回退
    style 仅仅修改了空格、格式缩进、逗号等等
    ... ...
  • 鼓励开发组成员之间互相 review 并 merge 代码到 dev 分支上。merge 前建议简单检查其 pull request 是否符合上述规范

  • 一般情况下,不要向 main 分支提出 pull request,更不要 merge 到 main 分支上

  • 一般情况下,不允许 merge 无法通过 CI 的 pull request

开发约定

  • 统一使用空格缩进而非制表符缩进
  • 统一使用 4 个空格进行缩进而非 2 个
  • 统一使用 UTF-8 字符编码

代码风格

本仓库严格规定了 C++CSharp 代码风格,具体配置请参见 .clang-format

风格说明

几项重要规定如下:

  • 需严格按照要求缩进

    namespace Exp
    {
        public class Program
        {
            public static void Main()
            {            
            }
        }
    }
  • ifwhile等关键字后须加空格

    while (1)
    {
        // code
    }
  • 大括号须换行书写

    // Allowed
    if (...)
    {
       // ... 
    }
    
    // Forbidden !!!
    if (...) {
        // ...
    }

规范代码风格

文档风格

仓库的文档使用 Markdown 语法,具体语法可以参照 Markdown 语法文档

中文文档的书写须严格遵循:中午技术文档规范中文文案排版指北,以写出更美观的中文文档。例如:中文文字与西文文字间空格全角标点符号的正确使用,等等。

西文文档的书写须遵循:

  • 中午技术文档规范中文文案排版指北 中规定的数字和西文的规范
  • 半角空格的标点符号的使用:
    • 半角的逗号 ,、分号 ;、句号 .、叹号 !、问号 ? 等标点,在不位于行尾时,后需加空格,除非其后紧跟全角标点符号。例如:"Hello, world",是一句学习编程语言常用的句子
    • 半角的括号 ()[]{}<> 等在左半括号前加空格、右半括号后加空格,除非其空格处紧跟全角标点符号或位于行首或行尾。例如:Tsinghua University (THU) and Peking University (PKU)(我是全角括号)

其他注意事项

  • 文件的字符编码格式须统一使用 UTF-8 编码,并用 4 空格缩进,尤其是 C/C++:Visual Studio 创建 cpp 文件时默认使用 GB2312 编码、TAB 缩进,因此每创建一个文件都需要注意手动设置字符编码(当代码文件中出现中文时)和缩进方式

  • 使用等宽字体进行编程,例如 Source Code Pro、Consolas 等,便于对齐

  • 注意代码的整洁性与可读性

    • 代码风格尽量统一。书写不要过于紧凑,善于使用空格、缩进与换行来让代码看起来更整洁

    • 命名风格尽量统一。相同类别的命名规则要相同,例如类名统一使用大驼峰命名法或其他常用的命名法,但是不要混用(非必要不使用匈牙利命名法)

    • 命名应当通俗易懂,让阅读代码者能够通过命名理解变量、函数等的意义。除循环变量等可以使用 ijk 等单字母外,其他的命名应当明白如话,且谨慎使用缩写。尽量使用众人皆知的缩写,不要自创缩写。如果连自己都不知道的缩写或根本没有众人皆知的缩写,则应当坚持使用全称,命名可以适当加长。

      常用的缩写有:

      address-addr、answer-ans、application-app、arguments-args、array-arr、assemble-asm、(a)synchronize-(a)sync、attribute-attr、begin-beg、bitmap-bmp、buffer-buf、button-btn、clock-clk、command-cmd、coordinates-coord、copy-cpy、count-cnt、current-cur、database-db、decrease-dec、default/define-def、delete-del、dependency-dep、destination-dest、device-dev、dialog-dlg、dictionary-dict、display-disp、divide-div、document-doc、educate-edu、equal-eq、error-err、extend-ext、format-fmt、frequency-freq、function-func、horizon-horz、image-img、implement-impl、increment-inc、index-idx、information-info、initialize-init、instance-inst、iterator-itr、length-len、list-lst、memory-mem、message-msg、middle-mid、number-num、object-obj、package-pkg、parameter-param、password-pwd、pointer-ptr、position-pos、previous-prev、receive-recv、reference-ref、resource/result-res、return-ret、second-sec、select-sel、semaphore-sem、signal-sig、source-src、stack-stk、standard-std、statistic/state-stat、string-str、system-sys、temporary-temp/tmp、text-txt、user-usr、value-val、variable-var、version-ver、vertical-vert、window-win

  • 命名允许较长,但不应过于啰嗦冗余,能完整表明意图即可。

  • 代码应保证良好的可读性;禁止中学 OI 竞赛的各种“卡常”奇技淫巧!!!效率并非总是最重要的,良好的可读性与可维护性往往更加重要

  • 熟练运用面向对象编程的**,设计架构时尽可能降低模块与模块的耦合性,保证代码的可维护性

    • 慎用全局变量、全局函数等

    • 尽可能将各功能模块化,便于日后复用;尽可能降低类与类的耦合,善用继承与多态

    • 适当设计单元测试,保证代码的正确运行

  • 注意跨平台问题,代码需保证同时支持 Windows 与 Linux,避免直接的系统调用带来的跨平台问题

  • 善于使用 Google 并使用英文搜索,善于查阅 Microsoft LearncppreferenceStackOverflow 以及第三方库官方文档等;不应轻信 CSDN 等劣质博客社区以及博客园简书等质量参差不齐的博客社区,对其内容需全方位多角度仔细求证方可相信

  • Pull requests 模板中的复选框采用 Markdown 格式:

    - [ ] 不勾选
    - [x] 勾选

    效果:

    • 不勾选
    • 勾选
  • 注意维护开发文档,便于后来者快速了解本仓库代码结构

  • 小组内合理分工,避免个人任务量过重或过轻

  • 做好部会记录,及时完成工作任务,避免拖延到 ddl

  • 各组间多交流,相互了解各自的开发进度,加强协作,遇到困难互相帮助

  • 加油,奥里给 ,冲冲冲

开发组成员

  • 逻辑组:黄淞、游笑权、高思研
  • 通信组:王溢寒、李羿璇
  • 界面组:杨思琪、刘腾旋
  • 运维组:庄继敏、王诗凯
  • 端茶倒水:唐昌礼

thuai6's People

Contributors

blitherboom812 avatar dragonaura avatar gsy1519 avatar jackyyang258 avatar l0510410 avatar m-x-05 avatar octaacid avatar renovate[bot] avatar sendssf avatar shangfengh avatar shawqeem avatar tcl606 avatar timothy-liuxf avatar wihn2021 avatar xiangmy21 avatar zzdhybthu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

thuai6's Issues

更新器更新加速

Is your feature request related to a problem? Please describe.
目前更新器在进行大规模更新时较慢,因此需要加速

Describe the solution you'd like
由于现在是一个一个文件轮番下载,而文件多且小的情况下会很慢,因此建议进行多线程并行下载

Describe alternatives you've considered
预先将要下载的文件放入线程安全的队列当中,开多个线程逐个取文件下载

Additional context

关于 `EndAllAction` 的实现问题(光速学习、卡墙等)

Describe the bug
现在的 EndAllAction 的实现逻辑有误,仅仅是改变了状态这个变量的值,却没有等待人物的状态真正地改变,从而导致穿墙(多重移动)、光速修机(多重修机)等多种 bug。

以移动为例,现在的停止状态代码:

public void ChangePlayerState(PlayerStateType value = PlayerStateType.Null, GameObj? gameObj = null)
{
lock (gameObjLock)
{
++threadNum;
whatInteractingWith = gameObj;
if (value != PlayerStateType.Moving)
IsMoving = false;
playerState = (value == PlayerStateType.Moving) ? PlayerStateType.Null : value;
//Debugger.Output(this,playerState.ToString()+" "+IsMoving.ToString());
}
}

在停止移动时,仅仅是把 IsMoving 置为 false,试图来通知移动线程停止移动,这存在问题:

  • 首先,移动线程没有真的停止,因为需要等到移动线程下一轮判断 IsMoving 后才能退出,而此时移动线程可能还在行走一步,但是,player 的状态已经改变了,所以这一刻如果有移动的指令发来,就会导致又开启了一个移动线程,这会造成双重移动。本质上的原因是,状态转移并没有真的完成真正的状态转移,没有真的停止人物的移动状态。应当是先通知人物停止移动,然后等待移动线程停止移动,最后再更改人物的移动状态为不移动允许新一轮移动。
  • IsMoving 的职责是用来表征人物是否在移动的, 而不是控制人物是否该移动的,职责混乱。理论上 IsMoving 应当仅由控制移动的 MoveManager 来更改。

To Reproduce
选手群里已经有很多这种例子了(

Expected behavior
以移动为例(修机自行类比),一个解决方案如下(没好好起命名):
每个可移动物体加一个尽可以 atomic 访问的 bool 变量,设为 flag,默认是 false;,加一个锁 mtx
MoveObj 的时候

void MoveObj()
{
        while (load(ref flag)) { 移动 }
    lock (mtx) {
        IsMoving = false;
        save(ref flag, false);
        Monitor.PulseAll(mtx);
    }
}

void StopMoving() {
    lock (mtx) {
        if (IsMoving) {
            save(ref flag, true);
            while (IsMoving) Monitor.Wait(mtx);
        }
    }
    SetStatus();
}

上述操作完全封装到移动引擎 MoveManager 中,flag 不要对外暴露。
这样,flag 仅用于通知移动线程停止移动,而 IsMoving

Additional context
之前在微信群写的有点错误,锁错了地方,现在改一下。。。

存在利用观战模式作弊的可能

Describe the bug

如果在比赛过程中允许观战,则智能体端可以通过观战接口,获取全局信息,从而实现作弊。不知道你们有没有对这个情况进行防御。

Expected behavior

也许可以通过观战时需要token来解决。

不同进程放在多个 Docker 容器内

Is your feature request related to a problem? Please describe.
现在的所有进程(Server, Client)都放在同一个 Docker 容器内运行,不利于内存限制、或者分开查看内存、CPU占用。

Describe the solution you'd like
可以通过在不同 Docker 容器内运行各个进程来解决。详情见下面的解决方案:
https://www.runoob.com/docker/docker-container-connection.html
即每一场比赛都创建一个 Network,各个 Client 连接到 Server。

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

关于选手接口的多线程问题

Describe the bug
目前选手等待下一帧的接口 Wait 在选手开启多线程,并且一起 Wait 的时候会出现小小的问题,可能会导致选手漏掉一些帧。

详情参见 eesast/THUAI5#107方法二

Expected behavior
允许漏帧(不修复了)或修复。

Additional context
其实不修复也没啥问题(x

bug related to read/write lock in server

Describe the bug
When running cpp version of players' code, the server might break down soon after the game starts. The timing of this seems to be in a random manner, sometimes not happening at all. As we're currently rewriting the entire .cpp file, we do not rule out multiple bugs in our own AI.cpp, but the info printed seems to point to a bug in Server. To ensure reproduction, please operate sevaral times.

To Reproduce
Steps to reproduce the behavior:

  1. Open RunServer.cmd
  2. Open RunCpp.cmd
  3. Happens with or without opening RunGUIClient.cmd

Expected behavior
The server should print nothing during the course of the game ,except for new spectators.

Screenshots
image
and meanwhile in GUI:

image

Additional context
I do not know whether this is related (perhaps we wrote erroneous commands in RunGUIClient.cmd), but the graphic interface refuse to open correctly if it is opened after RunCpp.cmd. The error feedback is as follows:
image

However, it will run correctly if opened after RunServer.cmd and before RunCpp.cmd. This does not interfere with actual programming ,but can be a little annoying.

关于 SendMessage 接口

Describe the bug
现在 SendMessage 使用了 string 类型发送消息,但是这样带来了只支持 UTF-8 字符串,而不支持 raw bytes 的问题。

Expected behavior
决赛时或许可以修改有关接口或者增加发送 bytes 的接口,以支持相关操作。

更新器前端代码

Is your feature request related to a problem? Please describe.
现在前端代码所有的页面 / 控件全部挤在一起,这可能不利于后续的维护和修改。有时间的话可以考虑重构一下。

Describe the solution you'd like
可以考虑使用类似于选项卡的方式组织各个页面,可以参考:
https://wpf-tutorial.com/zh/68/tabcontrol/%E4%BD%BF%E7%94%A8wpf-tabcontrol/

Describe alternatives you've considered
其他更好的方式也欢迎大家开脑洞)

Additional context
这是个,饼

2nd step: 实现队式中与网站交互的各个功能

Is your feature request related to a problem? Please describe.
目前可以进一步推进本地客户端的开发。

Describe the solution you'd like
可以添加的功能包括:本地提交代码文件、查看编译信息、查看天梯、发起对战、观看直播、下载回放等操作

Describe alternatives you've considered

  1. 与网站沟通相应的请求格式
  2. 可以考虑将 WPF 与 下载器集成

Additional context
暂无。

关于下载器的一个规范问题(for THUAI7)

刚刚发现目前 THUAI6 的配置文件是 %USERPROFILE%\Documents\THUAI6.json

dataPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
//dataPath = new DirectoryInfo(".").FullName;
Data.path = System.IO.Path.Combine(dataPath, "THUAI6.json");

实际上这个文件夹主要目的是用于存放用户的一些文档,而非应用配置数据。原则上讲,存放配置数据应该是:

  • %LOCALAPPDATA%:对应于 %USERPROFILE%\AppData\Local,用于存放本用户在本地计算机上的配置数据
  • %APPDATA%:对应于 %USERPROFILE%\AppData\Roaming,用于存放本用户的漫游配置数据
  • %ALLUSERSPROFILE%:对应于 %HOMEDRIVE%\ProgramData,用于存放所有用户的公共配置数据(一般由 Administrator 用户管理)

综上,咱们的 THUAI6 更适合存放在 %LOCALAPPDATA% 中。具体的规范是,在改文件夹下,再创建一个属于自己应用的文件夹,然后在该文件夹下存放配置数据。对于 THUAI6,一个可能的配置文件路径是:%LOCALAPPDATA%\THUAI6\config.json,例如上段代码改成如下的:

var dataDir = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "THUAI6");
if (!System.IO.Directory.Exists(dataDir))
{
    System.IO.Directory.CreateDirectory(dataDir);
}
var configPath = System.IO.Path.Combine(dataDir, "config.json");

然后将数据放在该 config.json 里(卸载时直接删除该 THUAI6 文件夹即可)。

不过鉴于 THUAI6 已经放在了 Documents 里,且临近决赛,为了选手的体验,不必更改。建议 THUAI7 的小同学可以改一下(将此 issue 遗传到 THUAI7),或者决赛结束之后你们有空也可以改一下(bushi

死锁问题

Describe the bug
Server 中存在潜在的死锁问题

To Reproduce
暂不清楚,但服务器上的确观察到此现象
微信图片_20230428224550

Desktop (please complete the following information):
Ubuntu 22.04

Additional context
死锁问题是非常严重的,将直接导致比赛不能正常进行。欢迎大家讨论一下当前死锁问题的原因,解决这个问题。以及如果发现了复现该问题的方式,可以在本 issue 中提出。

关于 Python 枚举

@DragonAura

Python 库有枚举类型:https://docs.python.org/zh-cn/3.7/library/enum.html
使用枚举类型的话,就不需要写那一坨 Dict 来把枚举变成字符串了(Python 不是 C++,都什么年代了程序员还需要手动存元数据 x)
一个 Demo 如下:

#!/usr/bin/env python3

from enum import IntEnum

class Gender(IntEnum):
    MALE = 1
    FEMALE = 2
    OTHER = 3

def main():
    s = Gender.OTHER
    print(s)    # Output 'Gender.OTHER'
    print(str(s).split('.')[-1]) # Print 'OTHER'

if __name__ == '__main__':
    main()

Unity 界面完善细节

目前 Unity 基础功能已经做好了,可以考虑进一步完善细节。例如:

  1. 用不同的动画效果呈现人物不同的状态
  2. 显示捣蛋鬼的攻击操作
  3. 实现以 Unity 为回放文件的默认打开方式
  4. 添加以玩家身份加入游戏的功能
  5. 生成安卓端应用,功能至少包括观看回放文件,可以添加观战、玩家操作等功能
  6. 更华丽的主界面
  7. 支持氪金获得更炫酷的粒子效果
  8. ……

关于 C++ API 的整数类型

@DragonAura 发现一个小问题。C++ 的 API 里面大部分用的都是 int32_tint64_t 之类的定长整数,而少数的 API 直接用的 int,这显得不是很一致与和谐,有时间可以改改(

// 获取游戏目前所进行的帧数
[[nodiscard]] virtual int GetFrameCount() const = 0;
/*****选手可能用的辅助函数*****/
// 获取指定格子中心的坐标
[[nodiscard]] static inline int CellToGrid(int cell) noexcept
{
return cell * numOfGridPerCell + numOfGridPerCell / 2;
}
// 获取指定坐标点所位于的格子的 X 序号
[[nodiscard]] static inline int GridToCell(int grid) noexcept
{
return grid / numOfGridPerCell;
}
[[nodiscard]] virtual bool HaveView(int gridX, int gridY) const = 0;

[[nodiscard]] int GetFrameCount() const override;

[[nodiscard]] bool HaveView(int gridX, int gridY) const override;

[[nodiscard]] int GetFrameCount() const override;

等等等等……

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Ignored or Blocked

These are blocked by an existing closed PR and will not be recreated unless you click a checkbox below.

Detected dependencies

dockerfile
dependency/Dockerfile/Dockerfile_base
  • python 3.9.16-bullseye
dependency/Dockerfile/Dockerfile_cpp
dependency/Dockerfile/Dockerfile_run
  • mcr.microsoft.com/dotnet/sdk 8.0.204-jammy-amd64
github-actions
.github/workflows/build.yml
  • actions/checkout v4
  • actions/setup-dotnet v3
.github/workflows/docker.yml
  • actions/checkout v4
.github/workflows/format.yml
  • actions/checkout v4
  • DoozyX/clang-format-lint-action v0.15
  • actions/checkout v4
  • actions/setup-dotnet v3
.github/workflows/mirror.yml
.github/workflows/upload_COS.yml
  • actions/checkout v4
  • actions/setup-dotnet v3
  • actions/setup-python v5
  • actions/upload-artifact v4
  • actions/checkout v4
  • actions/setup-dotnet v3
  • actions/setup-python v5
  • actions/download-artifact v4
  • BaileyJM02/markdown-to-pdf v1.2.0
  • zkqiang/tencent-cos-action v0.1.0
  • zkqiang/tencent-cos-action v0.1.0
gomod
experimental/CAPI/go/API/go.mod
  • go 1.18
nuget
dependency/proto/Protos.csproj
  • Grpc.Tools 2.62.0
  • Grpc.Core 2.46.6
  • Grpc 2.46.6
  • Google.Protobuf.Tools 3.26.1
  • Google.Protobuf 3.26.1
installer/Installer/Installer.csproj
  • Tencent.QCloud.Cos.Sdk 5.4.37
  • Newtonsoft.Json 13.0.3
  • Microsoft.Extensions.DependencyInjection.Abstractions 8.0.1
  • ICSharpCode.SharpZipLib.dll 0.85.4.369
installer/InstallerUpdater/InstallerUpdater.csproj
  • Tencent.QCloud.Cos.Sdk 5.4.37
  • Newtonsoft.Json 13.0.3
logic/Client/Client.csproj
  • Grpc.Core 2.46.6
  • Grpc 2.46.6
  • Google.Protobuf 3.26.1
  • FrameRateTask 1.2.0
  • CommandLineParser 2.9.1
logic/ClientTest/ClientTest.csproj
  • Grpc.Core 2.46.6
  • Grpc 2.46.6
  • Google.Protobuf 3.26.1
logic/GameEngine/GameEngine.csproj
  • FrameRateTask 1.2.0
logic/Preparation/Preparation.csproj
  • Google.Protobuf 3.26.1
logic/Server/Server.csproj
  • Newtonsoft.Json 13.0.3
  • Grpc.Tools 2.62.0
  • Grpc.Core 2.46.6
  • Grpc 2.46.6
  • Google.Protobuf 3.26.1
  • FrameRateTask 1.2.0
  • CommandLineParser 2.9.1
playback/Playback/Playback.csproj
  • Google.Protobuf 3.26.1
pip_requirements
CAPI/python/requirements.txt
  • grpcio ==1.54.2
  • grpcio-tools ==1.62.1

  • Check this box to trigger a request for Renovate to run again on this repository

关于 CAPI 的架构设计

基于访问者模式,实现对不同类对象的不同访问逻辑 @DragonAura
(里面的类名、接口名、方法名可以再重新斟酌斟酌,时间原因我起的比较草率)

interface IHumanAPI {
    // APIs
}

interface IBucherAPI {
    // APIs
}

interface IAI {
    void play(IHumanAPI&);
    void play(IBucherAPI&);
}

interface IGameTimer {
    void Start();
    void Stop();

    void StartGame(IAI&);
}

class HumanAI : IHumanAPI, IGameTimer {
    // APIs

    void StartGame(IAI& ai) {
        while (true) ai.play(*this);
    }
}

class BucherAI : IBucherAPI, IGameTimer {
    // APIs

    void StartGame(IAI& ai) {
        while (true) ai.play(*this);
    }
}

class AI : IAI {
    void play(IHumanAPI& human) {
        // do something
    }

    void play(IBucherAPI& bucher) {
        // do something
    }
}

然后 logic 可以这样写:

class Logic {
    IGameTimer& t;

    void Func() {
        auto ai = CreateAI();
        {
            t->Start();
            t->StartGame(ai);
            t->End();
        }
    }
}

1st step: 连接科协网站后端

Is your feature request related to a problem? Please describe.
目前队式在网站上发起对战后,并不能直接观看直播,而是需要等到游戏结束后下载回放文件看回放,这非常不方便。

Describe the solution you'd like
我们希望在本地连接网站后端,实现在本地就能在网站上发起对战,并实时观看直播。

Describe alternatives you've considered
目前第一步,我们可以先和网站组沟通,连接科协网站后端。

Additional context
暂无。

Action Required: Fix Renovate Configuration

There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.

Location: renovate.json
Error type: Invalid JSON (parsing failed)
Message: Syntax error: expecting String near "bot"], }

关于C#多线程中值类型set访问器的误导性

Describe the bug

private int hp = 0;
public int HP
{
  get
  {
    lock (gameObjLock)
    return hp;
  }
  set
  {
    lock (gameObjLock)
    hp = value;
  }
}
private int hp = 0;
public int HP
{
  get => Interlocked.CompareExchange(ref hp, -1, -1);
  set => Interlocked.Exchange(ref hp, value);
}

在多线程中,通常要对set与get访问器加锁或采用原子操作保证安全,但是这并不能保证完全安全合理
例如HP+=3;就是显然的错误
其相当与先调用get,再调用set,中间插入set操作将导致结果错误

这样可能导致set访问器具有误导性

Expected behavior
目前我进行中的修改方法是单独编写set或add方法
clgg建议可以采用结构体/类的方式来解决

应当令HP+=3;的写法在语法上不成立或者能够安全地编译
这个问题应该并非没有先例,想知道有什么更优雅的解决方案

Additional context
本issue与这个issue相关,但你不需要查看这个issue

更新器开启等待提示

Is your feature request related to a problem? Please describe.
更新器目前在启动后会静默等待一段时间,而没有提示,这不是很友好

Describe the solution you'd like
可以简单做个提示框

Describe alternatives you've considered

Additional context

关于选手接口目录结构问题

Is your feature request related to a problem? Please describe.

目前的选手接口目录结构:

.
|
+---CAPI
|   |   README.md
|   ...
+---PyAPI
|   |   README.md
|   ...
|
...

这样其实不算太好,如果以后多加语言的话可能还会导致根目录的子目录数爆炸,分工不甚清晰。

Describe the solution you'd like

建议是把选手接口都统一放在根目录的一个子目录(CAPI)下,不同语言的接口在 CAPI 里再分子目录

Describe alternatives you've considered

可能的一个目录结构:

.
|
+---CAPI
|   |
|   +---cpp
|   |   |   README.md
|   |   ...
|   +--- python
|   |   |   README.md
|   |   ...
|   |   README.md
|   ...
...

Additional context
Add any other context or screenshots about the feature request here.

关于 CAPI 中 logic 的一个可能存在的小小的问题

Describe the bug

ProcessMessage 中:

std::thread(messageThread).detach();

把该 threaddetach 掉了,这存在一个问题——
由于该线程捕获了 this
auto messageThread = [this]()

并且内部频繁访问 this 的内容,因此需要保证该线程运行过程中 this 指向的对象不析构。由于 this 指向的对象是 logic,因此要保证 logic 不析构。
注意到在 logic::Main 中:
logger->info("Connect to the server successfully, AI thread will be started.");
tAI = std::thread(AIThread);
if (tAI.joinable())
{
logger->info("Join the AI thread!");
// 首先开启处理消息的线程
ProcessMessage();
tAI.join();
}

tAI 运行结束之后 即结束,logic::Main 函数即退出:
Logic logic(playerType, pID, trickerType, stuType);
logic.Main(AIBuilder, sIP, sPort, file, print, warnOnly);
}
catch (const std::exception& e)

随即 logic 即析构。

tAI 的结束条件:

while (AILoop)
{
if (asynchronous)
{
Wait();
timer->StartTimer();
timer->Play(*ai);
timer->EndTimer();
}
else
{
Update();
timer->StartTimer();
timer->Play(*ai);
timer->EndTimer();
}
}

需要 AILoopfalse,而 ProcessMessage 函数中:
AILoop = false;
{
std::lock_guard<std::mutex> lock(mtxBuffer);
bufferUpdated = true;
counterBuffer = -1;
}
cvBuffer.notify_one();
logger->info("Game End!");
};
std::thread(messageThread).detach();

AILoop 置为 false 后,仍然要访问 mtxBuffer 等等 this 的内容。因此在游戏结束后,此选手接口有一定的崩掉的可能,可能不会正常退出。
但是由于这是在游戏结束后发生的,对比赛影响不大,但是一旦出现的话可能会稍影响体验。

Expected behavior

最好保证正常退出

Additional context

个人建议是:

  • 上策:不进行 detach,而是让其正常结束并 join
  • 中策:保证 AILoop 置为 false 后不再访问此对象
  • 下策:无视此问题,反正影响不大()

解决穿模问题

Is your feature request related to a problem? Please describe.
当人物在翻窗时,为了避免可能的问题,现在允许穿模,但这可能导致更多的问题。

Describe the solution you'd like
可以用以下方法避免穿模:
当人物翻窗或出现可能穿模的情况时,将出现穿模的人物顺移:直接将该人物顺移到一个安全的地方,即短时间内不可能与任何人重叠的地方。

可以参考的做法如下:将地图分成若干格,当人物 A 将与人物 B 重叠时,暴力搜索到一个任何人物短时间内达不到、且离重叠人物 B 最近的格子,将 A 顺移到该格子处。

GUI 简易调试界面深色主题

Is your feature request related to a problem? Please describe.
目前 WPF 的 GUI 简易调试界面是浅色主题,底色为纯白,这对深夜写代码和习惯暗色的选手不是特别友好。

Describe the solution you'd like
可以考虑增加深色主题,选手可以选择浅色或深色,或跟随操作系统深浅色设置。

Describe alternatives you've considered
不知道 WPF / UWP / WinUI3 / MAUI 都有没有现成的轮子可以用(个人感觉至少后三者是有的)

Additional context
作为未来的饼吧(

关于 logic 的一个遗留问题

Describe the bug
在:#162 (comment) 中描述了这点,是我自己以前的锅,之后看看如何改吧。

Expected behavior
消除 data race

Additional context
Add any other context about the problem here.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.