GithubHelp home page GithubHelp logo

equim-chan / mortal Goto Github PK

View Code? Open in Web Editor NEW
829.0 26.0 112.0 3.21 MB

🚀🀄️ A fast and strong AI for riichi mahjong, powered by Rust and deep reinforcement learning.

Home Page: https://mortal.ekyu.moe

License: GNU Affero General Public License v3.0

Dockerfile 0.13% Rust 86.09% JavaScript 0.66% Python 13.11% Shell 0.02%
ai deep-learning game-ai mahjong reinforcement-learning riichi mjai mahjong-ai

mortal's Introduction

Mortal

GitHub Workflow Status GitHub Workflow Status dependency status GitHub top language Lines of code GitHub code size in bytes license

Donate

Mortal (凡夫) is a free and open source AI for Japanese mahjong, powered by deep reinforcement learning.

Read the Documentation for everything about this work.

Okay cool now give me the weights!

Read this post for details regarding this topic.

License

Code

AGPL-3.0-or-later

Copyright (C) 2021-2022 Equim

This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License along with this program. If not, see https://www.gnu.org/licenses/.

Logo and Other Assets

CC BY-SA 4.0

mortal's People

Contributors

equim-chan avatar hyskylord avatar smly avatar wongsingfo 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  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  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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mortal's Issues

one_vs_three.py: failed to kill akochan: Access is denied. (os error 5)

Hi,

I am trying to test Mortal vs Akochan and I get the following error:

C:\Users\****\anaconda3\envs\Mortal\python.exe C:/Users/****/source/repos/Mortal/mortal/one_vs_three.py
--------------------------------------------------
# 0
2022-07-14 19:47:58,547     INFO one_vs_three.rs:140  seed: [10000, 10500) w/ 16962033399555274180, start 500 groups, 2000 hanchans
2022-07-14 19:48:16,421    ERROR   akochan.rs:77   failed to kill akochan: Access is denied. (os error 5)
Traceback (most recent call last):
  File "C:\Users\****\source\repos\Mortal\mortal\one_vs_three.py", line 86, in <module>
    main()
  File "C:\Users\****\source\repos\Mortal\mortal\one_vs_three.py", line 67, in main
    rankings = env.ako_vs_py(
RuntimeError: pipe is being closed. (os error 232)

I tried to run command line with admin previledge but the issue still persists.

ImportError: DLL load failed while importing libriichi: 找不到指定的模块。

我重新下载了Mortal的源码并进行build,运行train_grp后,报以下错误:
File "E:\mortal\mortal\train_grp.py", line 14, in
from model import GRP
File "E:\mortal\mortal\model.py", line 8, in
from libriichi.consts import obs_shape, oracle_obs_shape, ACTION_SPACE, GRP_SIZE
ImportError: DLL load failed while importing libriichi: 找不到指定的模块。
将最新的libriichi.pyd替换成mortal3 230109版本即可正常运行。
conda虚拟环境:python3.10+pytorch1.13.0(cuda11.7)(该环境可以正常运行mortal3 230109)
系统环境:windows server2019

Potential overflow

This line reserves 4 ArrayVec with capacity of 24 to record kawa.

pub(super) kawa: [ArrayVec<[Option<KawaItem>; 24]>; 4],

Which isn't adequate because this lines can push at most 8 None into it .

pub(super) fn pad_kawa_for_pon_or_daiminkan(&mut self, abs_actor: u8, abs_target: u8) {
let mut i = (abs_target + 1) % 4;
while i != abs_actor {
let rel = self.rel(i);
self.kawa[rel].push(None);
i = (i + 1) % 4;
}
}

In my test , program sometimes crash at this line.

self.kawa[actor_rel].push(Some(KawaItem {

about q_values not match action type

mortal 输出:
{'type': 'none', 'meta': {'q_values': [1.2168403, 0.33200026], 'mask_bits': 43980465111040, 'is_greedy': True, 'batch_size': 1, 'eval_time_ns': 39468600, 'shanten': 0, 'at_furiten': False}}

拆解mask_bists得到 (1<<43) | (1<<45)
对应q_values结果是 荣和 优先于 跳过,但是为什么mortal的实际操作却是跳过呢,本地运行mjai-reviewer运行结果下图所示
image

1v3报错

1v3的config设置为800 200时可以运行 但设置为2000 500时则报错 如图
image

AssertionError: raw_count == S.buffer_size

在online训练时server.py偶尔会出现这个错误,目前移除了这个assert来使用但是不明白为什么会产生这个错误。所有程序均在本地运行。

Possible cooperations

Hi, I just say your mortal AI project, I'm impressed by it. Is it possible to contect you and talk in some way? We have some project that might need someone like you.

no baseline.pth file

when I tried to run train.py ,I met this question

No such file or directory: '/content/drive/MyDrive/Mortal-main/mortal/baseline.pth'.

can u help how to solve this question

Testing with akochan

Hello, recently I have been training the Mortal model, but I encountered difficulties when testing it with akochan. My approach involves using the py_vs_akochan method in the one_vs_three environment. Although I anticipated that akochan would require a significant amount of CPU and memory resources during the simulations, I didn't expect the CPU pressure to become so overwhelming that testing became impossible. The program crashes when simulating over 50 groups for the half-dealer testing. Additionally, when I tried reducing the number of half-dealer simulations, I noticed that the testing program consistently consumes a large amount of server memory, indicating a potential memory leak.

I saw in your documentation that you conducted battles between akochan and mortal, but it seems that you only performed tens of thousands of half-dealer matches compared with hanchans between different versions of Mortal. Did you also encounter this issue? I would like to ask what method you used to successfully complete the testing. Thank you.

compile数据干扰

在V4的训练过程中遇到了一个现象,运行了testplay之后学习速度会降低大概15%,如图所示。经过研究推测test时的优化干扰了性能。目前临时的解决办法是torch._dynamo.reset(),副作用则是每次testplay之后都要重新compile一遍model。不知道有没有更好的解决办法。

image

名次计算可能有bug?

将challenger和champion设置为相同跑one_vs_three,按道理得到每一个名次的次数是相同的,但实际上并不一样,下面是其中一段结果

# 19
2022-08-17 10:41:31,151     INFO one_vs_three.rs:141  seed: [19500, 20000) w/ 10671399319166252728, start 500 groups, 2000 hanchans
o steps: 1182 (3.581 step/s)
[00:05:30] [#########################################################################################################################################################################] 2000/2000 100%2022-08-17 10:47:01,217     INFO one_vs_three.rs:208  dumping game logs
challenger rankings: [499 502 499 500] (2.5, 0.0pt)
--------------------------------------------------
# 20
2022-08-17 10:47:35,629     INFO one_vs_three.rs:141  seed: [20000, 20500) w/ 10671399319166252728, start 500 groups, 2000 hanchans
o steps: 1342 (3.815 step/s)
[00:05:51] [#########################################################################################################################################################################] 2000/2000 100%2022-08-17 10:53:27,451     INFO one_vs_three.rs:208  dumping game logs
challenger rankings: [500 500 497 503] (2.5015, -0.2025pt)

[Bug] Online Service Failed?

When I visit https://mjai.ekyu.moe, it fails.
I have pinged the mjai.ekyu.moe, dns is well, but the package lost 100%.
My network is using http proxy.
Why?
Is your service failed or my proxy setting is banned for your service?

If I want to start model training from scratch

Hi, I had a difficulty when I tried to start training a model using the Mortal source code.
When I try to run "train.py", it loads the trained model from the config file for the "test_player" and starts training the model.
I would like a clue as to what to do if I don't have a trained model for "test_player".

compliling libriichi on linux(ubuntu)

Hi! When I try to build libriichi module, the compilation stops at the link stage and returns a very long linker error message. I compile this code on Linux.
I find that this error is related to pyo3's feature extension module, since when disabling this feature, cargo can build or test smoothly.
Also, this linker erro only occurs in linux environment, and everything is fine when building libriichi on my windows system.
Did you run into the same problem, and can you help me with that? Thank you very much

error: linking with cc failed: exit status: 1
|
= note: "cc" "-m64" "/tmp/rustcPH0w39/symbols.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.10v5efmy67kgnpfa.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.13ofdr15yow88mrx.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.17mqin63awxyphus.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.18a77o4x61eeizd.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.1ctjkrd5bqnxird4.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.1g8g6r00hn6k1dky.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.1gq3as0zljndkm50.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.1iqnz75m4nq7ecb8.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.1k78n75cuy8wtllt.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.1ldm5a1reef9zwwg.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.1lz2wjxnc410lpsx.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.1noref0ejh9vm4g9.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.1pj1dmktnrd3wiz2.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.1shna44j1h84y18i.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.1t4qa9y1pb1q0xub.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.1uxsj5jzdc0wgjpx.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.1wtvk7r7zldukbki.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.1xhvg7r6rgkfzw5n.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.20n0tbpx2vx07bp5.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.22zn4i7ubkvg1yqb.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.24oxszmnamx0aq2l.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.29fh9pi8e6uxgphy.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.2d66fxm448jtgoqk.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.2e0jcq6hho2wjd4.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.2hw18hkilahqahl4.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.2ik26157irjegx3b.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.2kmprtcc8x97zsm2.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.2rr4x0opbwooo8bq.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.2x575inubnfetg3l.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.2zk9exuhzqqaytil.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.30e27ottgo2yahe0.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.38h8nf3clxwvm4i3.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.3aa8vd496gb7xe2v.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.3anhchmfd2t1jnjf.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.3fyiyy5i10hw94uz.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.3je8xugqv3qnqs8a.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.3jgafmcuht3arg11.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.3n3r256431mwe2b0.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.3ymdntaf4ywyqhqg.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.44jq980p8p1wo0mm.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.46a4fijgc9tf3erw.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.4790rjuaimaiix6r.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.498su1d4jcp3nkt3.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.49gwllk0h9l3e6rr.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.4apksw1au7z3knah.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.4cblk16be8ui10nh.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.4d53jrlx3hg9750o.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.4h7ag912qg1w5q1k.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.4iqc8jn2nwg5gxnr.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.4m72ma58cgwle6k5.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.4sxlyijxfshcxbgu.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.4tsg4mzo7mffj5mt.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.4uyigpg14bqri04g.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.58eyz3gymszkanbq.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.5ffprosdt517v0j1.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.5fziidf7ilpt031n.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.7zlp9fvs3ql0cdh.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.92et92jl4dksrna.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.bu0ccgjk85acmuf.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.dqioxsykxdnemti.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.gci44w1mfywgw5l.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.i94usgo17uc5sqa.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.jiguoa08gxk0xob.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.ki1fge18g8g0ots.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.krt4f04ycmkwsfs.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.o3yw41oy9xssd0i.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.pvvloaj5xpcywy3.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.sjl10va7ewhyxih.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.wd95pbxwi11539u.rcgu.o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300.3wrud4jobickhfii.rcgu.o" "-Wl,--as-needed" "-L" "/home/zcwang/riichi/Mortal/target/debug/deps" "-L" "/home/zcwang/riichi/Mortal/target/debug/build/libmimalloc-sys-6e38240a4e3aa23f/out" "-L" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-Wl,-Bstatic" "/home/zcwang/riichi/Mortal/target/debug/deps/libriichi.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libpyo3_log-8dcda3a1ac38e31d.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libarc_swap-e1fdd8e3f9170c99.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libmimalloc-4c0b48abe61389a7.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/liblibmimalloc_sys-68d9ad77157f3561.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libbyteorder-5f7435338104d45b.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libboomphf-2ef9f47145aeadb5.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libwyhash-db52949e4468a1ba.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/liblog-9ba82ae789949f1a.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libglob-09d67aea6e036533.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libserde_with-a08bcdc2650f9f08.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libnumpy-e55762671f6be14d.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/librustc_hash-dba33981d384e54c.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libahash-56c084b50baf3c4e.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libonce_cell-406ec8035d14a065.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libserde_json-4996a893a2b68b60.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libryu-0b5fa5715bb0d01a.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libitoa-7b8a3ee6006bf7d8.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libpyo3-365fe8b69d5212bb.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libparking_lot-66101a7ea323d866.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libparking_lot_core-a566e571b8028509.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libsmallvec-eff21c5aff60ab5c.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/liblock_api-085ab99679bcd5c0.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libpyo3_ffi-c2ac8ce566c6b819.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libinventory-869aa4ad51c25b87.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libunindent-4711929fc6abf911.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libflate2-1ada63e168383969.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libminiz_oxide-dadb4324db4b23c8.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libadler-c379f1fd15ae26d4.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libcrc32fast-85506f1f6fc33fcf.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libindicatif-5baf76df4c9b2d7a.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libportable_atomic-ae2d1f307fd78b73.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/librayon-9bdba68f95147a8c.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/librayon_core-7cd1fa23c3c6358d.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libnum_cpus-61fb7447d47ff89b.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libcrossbeam_deque-78883dc4f04621e3.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libcrossbeam_epoch-d9f7e1e048644832.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libmemoffset-e7ef8e5a73af8af8.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libscopeguard-7001a141a39e01e2.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libcrossbeam_channel-d3df9c01e90b4fc8.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libcrossbeam_utils-df9ff32d998ccc95.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libeither-494454c5804442fc.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libnumber_prefix-6163d702f4a62401.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libconsole-7c78ce8282e00882.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libunicode_width-7617736720435385.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/liblazy_static-b8e931bc1934af0c.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libtinyvec-865a77be667159b8.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libtinyvec_macros-3d7b4db04965d89a.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libserde-31053e9ceccc8acb.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libsha3-d36e6281b575e45c.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libkeccak-51ee9301273e298f.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libdigest-0af189b3f3bb8008.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libblock_buffer-ba4f8cb1f6991d67.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libcrypto_common-f1020b06d07e922c.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libgeneric_array-b9b323084fc006c6.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libtypenum-64711f45ff693bd7.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/librand-cf793c220e4ffe2c.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/librand_chacha-d22f03fe1ace7757.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libppv_lite86-e7978653219548f0.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/librand_core-13020919910cf3ba.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libgetrandom-9cd8334c95dec545.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/liblibc-8212084bd967f467.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libcfg_if-06b0b01aa334fc1b.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libndarray-67ad3167c8027991.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libmatrixmultiply-1c42e633fb8d8839.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libnum_complex-e9e5cea14ba58d63.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libnum_integer-39e365f965ea383a.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libnum_traits-b469ff2240fcf287.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/librawpointer-97946820b0d25a50.rlib" "/home/zcwang/riichi/Mortal/target/debug/deps/libanyhow-2bfd9dc32153eec0.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-cc54747a4cc2b42a.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_unwind-64c2149e46f4b352.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/libobject-b2c727373694f03a.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/libmemchr-2a47a846ca0c41be.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/libaddr2line-794a77eb0c487d83.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/libgimli-23c4931a4edea386.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_demangle-1e140f87d627e46d.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd_detect-f396ed5291fd3454.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/libhashbrown-401d7002ec69df8e.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/libminiz_oxide-afcf3708f7250165.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/libadler-afb73f721c839ff5.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_alloc-1e56c8705be9ad51.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunwind-c2085ef1fa30c0b6.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcfg_if-b1838ea366d802c9.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-6d5e9308242df554.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-922a5da03a4b65c7.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_core-e0c666df99a8c710.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-9550e2105c24ab24.rlib" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-3f7dd70c559ae534.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-Wl,--eh-frame-hdr" "-Wl,-znoexecstack" "-L" "/usr/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-o" "/home/zcwang/riichi/Mortal/target/debug/deps/validate_logs-4c192e21484bc300" "-Wl,--gc-sections" "-pie" "-Wl,-zrelro,-znow" "-nodefaultlibs"
= note: /usr/bin/ld: /home/zcwang/riichi/Mortal/target/debug/deps/libriichi.rlib(riichi.1tccjjd3b9609jl1.rcgu.o): in function pyo3::types::string::PyString::to_str': /home/zcwang/.cargo/registry/src/github.com-1ecc6299db9ec823/pyo3-0.19.0/src/types/string.rs:189: undefined reference to PyUnicode_AsUTF8AndSize'
/usr/bin/ld: /home/zcwang/riichi/Mortal/target/debug/deps/libriichi.rlib(riichi.1tccjjd3b9609jl1.rcgu.o): in function `pyo3_ffi::object::PyObject_TypeCheck':

      [many, many path]

      /usr/bin/ld: /home/zcwang/riichi/Mortal/target/debug/deps/libpyo3-365fe8b69d5212bb.rlib(pyo3-365fe8b69d5212bb.pyo3.054e2e17-cgu.9.rcgu.o): in function `pyo3::types::string::PyString::to_string_lossy':
      /home/zcwang/.cargo/registry/src/github.com-1ecc6299db9ec823/pyo3-0.19.0/src/types/string.rs:216: undefined reference to `PyUnicode_AsEncodedString'
      collect2: error: ld returned 1 exit status

= help: some extern functions couldn't be found; some native libraries may need to be installed or have their path specified
= note: use the -l flag to specify native libraries to link
= note: use the cargo:rustc-link-lib directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-link-libkindname)

error: could not compile libriichi due to previous error

対人オンラインを作ることは可能でしょうか?

こんにちは

オンライン対人麻雀、を作りたいと考えています。

このmortalを使って、作ることは可能でしょうか?

・python 部分だけを改変
・rust、部分はいじらない

これが、理想の条件です。

よろしくおねがいします。

万二郎

多面听立直,无法选择立哪张

{"type": "start_game"}
{"type": "start_kyoku", "bakaze": "E", "kyoku": 3, "honba": 0, "kyotaku": 0, "oya": 0, "dora_marker": "9s", "scores": [19800, 26300, 36000, 17900], "tehais": [["?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?"], ["1m", "8m", "9m", "1p", "3p", "5p", "6p", "7p", "3s", "6s", "7s", "8s", "N"], ["?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?"], ["?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?"]]}
{"type": "dahai", "actor": 2, "pai": "2m", "tsumogiri": false}
{"type": "tsumo", "actor": 3, "pai": "?"}
{"type": "dahai", "actor": 3, "pai": "N", "tsumogiri": false}
{"type": "tsumo", "actor": 0, "pai": "?"}
{"type": "dahai", "actor": 0, "pai": "W", "tsumogiri": false}
{"type": "tsumo", "actor": 1, "pai": "2p"}
{"type": "dahai", "actor": 1, "pai": "N", "tsumogiri": false}
{"type": "tsumo", "actor": 2, "pai": "?"}
{"type": "dahai", "actor": 2, "pai": "9s", "tsumogiri": false}
{"type": "tsumo", "actor": 3, "pai": "?"}
{"type": "dahai", "actor": 3, "pai": "P", "tsumogiri": false}
{"type": "tsumo", "actor": 0, "pai": "?"}
{"type": "dahai", "actor": 0, "pai": "S", "tsumogiri": false}
{"type": "tsumo", "actor": 1, "pai": "E"}
{"type": "dahai", "actor": 1, "pai": "E", "tsumogiri": true}
{"type": "tsumo", "actor": 2, "pai": "?"}
{"type": "dahai", "actor": 2, "pai": "4m", "tsumogiri": false}
{"type": "tsumo", "actor": 3, "pai": "?"}
{"type": "dahai", "actor": 3, "pai": "C", "tsumogiri": false}
{"type": "tsumo", "actor": 0, "pai": "?"}
{"type": "dahai", "actor": 0, "pai": "C", "tsumogiri": false}
{"type": "tsumo", "actor": 1, "pai": "4s"}
{"type": "dahai", "actor": 1, "pai": "1m", "tsumogiri": false}
{"type": "tsumo", "actor": 2, "pai": "?"}
{"type": "dahai", "actor": 2, "pai": "7m", "tsumogiri": false}
{"type": "tsumo", "actor": 3, "pai": "?"}
{"type": "dahai", "actor": 3, "pai": "C", "tsumogiri": true}
{"type": "tsumo", "actor": 0, "pai": "?"}
{"type": "dahai", "actor": 0, "pai": "E", "tsumogiri": false}
{"type": "tsumo", "actor": 1, "pai": "P"}
{"type": "dahai", "actor": 1, "pai": "P", "tsumogiri": true}
{"type": "tsumo", "actor": 2, "pai": "?"}
{"type": "dahai", "actor": 2, "pai": "9m", "tsumogiri": false}
{"type": "tsumo", "actor": 3, "pai": "?"}
{"type": "dahai", "actor": 3, "pai": "7s", "tsumogiri": false}
{"type": "tsumo", "actor": 0, "pai": "?"}
{"type": "dahai", "actor": 0, "pai": "8s", "tsumogiri": false}
{"type": "tsumo", "actor": 1, "pai": "9s"}
{"type": "dahai", "actor": 1, "pai": "8m", "tsumogiri": false}
{"type": "tsumo", "actor": 2, "pai": "?"}
{"type": "dahai", "actor": 2, "pai": "P", "tsumogiri": false}
{"type": "tsumo", "actor": 3, "pai": "?"}
{"type": "dahai", "actor": 3, "pai": "F", "tsumogiri": true}
{"type": "tsumo", "actor": 0, "pai": "?"}
{"type": "dahai", "actor": 0, "pai": "1p", "tsumogiri": false}
{"type": "tsumo", "actor": 1, "pai": "N"}
{"type": "dahai", "actor": 1, "pai": "9m", "tsumogiri": false}
{"type": "tsumo", "actor": 2, "pai": "?"}
{"type": "dahai", "actor": 2, "pai": "E", "tsumogiri": false}
{"type": "tsumo", "actor": 3, "pai": "?"}
{"type": "dahai", "actor": 3, "pai": "S", "tsumogiri": true}
{"type": "tsumo", "actor": 0, "pai": "?"}
{"type": "dahai", "actor": 0, "pai": "1p", "tsumogiri": false}
{"type": "tsumo", "actor": 1, "pai": "1m"}
{"type": "dahai", "actor": 1, "pai": "1m", "tsumogiri": true}
{"type": "tsumo", "actor": 2, "pai": "?"}
{"type": "dahai", "actor": 2, "pai": "E", "tsumogiri": false}
{"type": "tsumo", "actor": 3, "pai": "?"}
{"type": "dahai", "actor": 3, "pai": "7s", "tsumogiri": false}
{"type": "tsumo", "actor": 0, "pai": "?"}
{"type": "dahai", "actor": 0, "pai": "1m", "tsumogiri": true}
{"type": "tsumo", "actor": 1, "pai": "8m"}
{"type": "dahai", "actor": 1, "pai": "8m", "tsumogiri": true}
{"type": "pon", "actor": 3, "target": 1, "pai": "8m", "consumed": ["8m", "8m"]}
{"type": "dahai", "actor": 3, "pai": "7m", "tsumogiri": false}
{"type": "tsumo", "actor": 0, "pai": "?"}
{"type": "dahai", "actor": 0, "pai": "S", "tsumogiri": false}
{"type": "tsumo", "actor": 1, "pai": "6p"}
{"type": "dahai", "actor": 1, "pai": "N", "tsumogiri": false}
{"type": "tsumo", "actor": 2, "pai": "?"}
{"type": "dahai", "actor": 2, "pai": "C", "tsumogiri": true}
{"type": "tsumo", "actor": 3, "pai": "?"}
{"type": "dahai", "actor": 3, "pai": "6s", "tsumogiri": true}
{"type": "tsumo", "actor": 0, "pai": "?"}
{"type": "dahai", "actor": 0, "pai": "4s", "tsumogiri": false}
{"type": "tsumo", "actor": 1, "pai": "1s"}
{"type": "dahai", "actor": 1, "pai": "6p", "tsumogiri": false}
{"type": "tsumo", "actor": 2, "pai": "?"}
{"type": "dahai", "actor": 2, "pai": "3s", "tsumogiri": true}
{"type": "tsumo", "actor": 3, "pai": "?"}
{"type": "dahai", "actor": 3, "pai": "6m", "tsumogiri": true}
{"type": "tsumo", "actor": 0, "pai": "?"}
{"type": "dahai", "actor": 0, "pai": "2s", "tsumogiri": false}
{"type": "tsumo", "actor": 1, "pai": "3m"}
{"type": "dahai", "actor": 1, "pai": "3m", "tsumogiri": true}
{"type": "pon", "actor": 3, "target": 1, "pai": "3m", "consumed": ["3m", "3m"]}
{"type": "dahai", "actor": 3, "pai": "3p", "tsumogiri": false}
{"type": "tsumo", "actor": 0, "pai": "?"}
{"type": "dahai", "actor": 0, "pai": "4p", "tsumogiri": false}
{"type": "reach", "actor": 0}
{"type": "tsumo", "actor": 1, "pai": "5pr"}
{"type": "dahai", "actor": 1, "pai": "9s", "tsumogiri": false}
{"type": "chi", "actor": 2, "target": 1, "pai": "9s", "consumed": ["7s", "8s"]}
{"type": "dahai", "actor": 2, "pai": "F", "tsumogiri": false}
{"type": "tsumo", "actor": 3, "pai": "?"}
{"type": "dahai", "actor": 3, "pai": "7p", "tsumogiri": false}
{"type": "tsumo", "actor": 0, "pai": "?"}
{"type": "dahai", "actor": 0, "pai": "1m", "tsumogiri": true}
{"type": "tsumo", "actor": 1, "pai": "2s"}
{"type": "dahai", "actor": 1, "pai": "5p", "tsumogiri": false}
{"type": "reach", "actor": 1}
{"type": "hora", "actor": 0, "target": 1, "deltas": [5500, -4500, 0, 0], "ura_makers": []}
{"type": "end_kyoku"}

只有立直选项,没有选择出哪张立直宣言牌

image

请问mortal2代比1代强度到底怎么样呢?

我最近发现2代官网上显示是b75c256,层数比1代的b40c192多了许多,应该更强。
但是看文档里strength似乎打不过1代,这是为什么啊?这个AI是强化学习,不应该和所用数据集有太大关联吧。作者能不能解答下这个疑惑,谢谢!

[Train Error] tensorboud writer.add_histogram reported an error

numpy 1.24+ 对数据类型更加严格导致train报错

Traceback (most recent call last):
  File "/root/Mortal/mortal/train.py", line 424, in <module>
    main()
  File "/root/Mortal/mortal/train.py", line 402, in main
    train()
  File "/root/Mortal/mortal/train.py", line 383, in train
    train_epoch()
  File "/root/Mortal/mortal/train.py", line 264, in train_epoch
    writer.add_histogram('q_predicted', all_q_1d, steps)
  File "/root/miniconda3/envs/mortal/lib/python3.10/site-packages/torch/utils/tensorboard/writer.py", line 485, in add_histogram
    histogram(tag, values, bins, max_bins=max_bins), global_step, walltime
  File "/root/miniconda3/envs/mortal/lib/python3.10/site-packages/torch/utils/tensorboard/summary.py", line 358, in histogram
    hist = make_histogram(values.astype(float), bins, max_bins)
  File "/root/miniconda3/envs/mortal/lib/python3.10/site-packages/torch/utils/tensorboard/summary.py", line 386, in make_histogram
    cum_counts = np.cumsum(np.greater(counts, 0, dtype=np.int32))
TypeError: No loop matching the specified signature and casting was found for ufunc greater

降级1.23临时解决 pip install numpy==1.23

Fail to run doc test under `libriichi`

First I try to run tests under libriichi directly and get errors like

> cd Mortal/libriichi
>  cargo test
    Finished test [unoptimized + debuginfo] target(s) in 0.09s
     Running unittests src/lib.rs (/path/to/Mortal/target/debug/deps/riichi-47b47cdd3de647c5)
dyld[69996]: symbol not found in flat namespace '_PyBaseObject_Type'
error: test failed, to rerun pass '--lib'

Caused by:
  process didn't exit successfully: `/path/to/Mortal/target/debug/deps/riichi-47b47cdd3de647c5` (signal: 6, SIGABRT: process abort signal)

Then I follow the FAQ of pyo3 i-cant-run-cargo-test and get errors like

>  cargo test --no-default-features
   Compiling pyo3 v0.15.2
   Compiling numpy v0.15.1
   Compiling libriichi v0.1.0 (/path/to/Mortal/libriichi)
    Finished test [unoptimized + debuginfo] target(s) in 4.85s
     Running unittests src/lib.rs (/path/to/Mortal/target/debug/deps/riichi-069c85f8695c006a)

running 21 tests
test hand::test::parse ... ok
test arena::result::test::rankings ... ok
test macros::test::completeness ... ok
test hand::test::string ... ok
test macros::test::syntax ... ok
test state::test::can_chi ... ok
test algo::agari::test::agari_calc ... ok
test algo::shanten::test::calc_3n_plus_3 ... ok
test algo::shanten::test::calc_3n_plus_1 ... ok
test algo::shanten::test::calc_3n_plus_2 ... ok
test state::test::dora_count_after_kan ... ok
test state::test::get_rank ... ok
test state::test::furiten ... ok
test algo::agari::test::ankan_after_riichi ... ok
test state::test::waits ... ok
test tile::test::next_prev ... ok
test state::test::rule_based_agari_all_last_minogashi ... ok
test state::test::kakan_from_hand ... ok
test state::test::double_chankan_ron ... ok
test state::test::discard_candidates_with_unconditional_tenpai ... ok
test arena::game::test::tsumogiri ... ok

test result: ok. 21 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.68s

     Running unittests src/bin/stat.rs (/path/to/Mortal/target/debug/deps/stat-fba45acd61b1da13)

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

     Running unittests src/bin/validate_logs.rs (/path/to/Mortal/target/debug/deps/validate_logs-6345802e6d8664c1)

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests riichi

running 1 test
test src/agent/batchify.rs - agent::batchify::BatchifiedAgent<A>::new (line 23) ... FAILED

failures:

---- src/agent/batchify.rs - agent::batchify::BatchifiedAgent<A>::new (line 23) stdout ----
error[E0432]: unresolved import `riichi::agent::Tsumogiri`
 --> src/agent/batchify.rs:24:50
  |
4 | use riichi::agent::{BatchAgent, BatchifiedAgent, Tsumogiri};
  |                                                  ^^^^^^^^^ no `Tsumogiri` in `agent`

error[E0603]: module `agent` is private
  --> src/agent/batchify.rs:24:13
   |
4  | use riichi::agent::{BatchAgent, BatchifiedAgent, Tsumogiri};
   |             ^^^^^ private module
   |
note: the module `agent` is defined here
  --> /path/to/Mortal/libriichi/src/lib.rs:11:1
   |
11 | mod agent;
   | ^^^^^^^^^^

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0432, E0603.
For more information about an error, try `rustc --explain E0432`.
Couldn't compile the test.

failures:
    src/agent/batchify.rs - agent::batchify::BatchifiedAgent<A>::new (line 23)

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.04s

error: test failed, to rerun pass '--doc'

about dataset

image

Which kind of .json.gz dataset is required? I downloaded .json from majsoul and compressed to .gz but mortal can't read it.

Installation problems with pytorch

You recommand installing pytorch with pip.
But I found that the default installation is the cpu version of PyTorch.

I tried to test your code and got the error:
AssertionError: Torch not compiled with CUDA enabled

It is recommended to specify the GPU version of PyTorch to be used in the documentation
BTW I used this code to install PyTorch and fix the cuda error reporting problem
pip install torch==1.8.0+cu111 torchvision==0.9.0+cu111 torchaudio===0.8.0 -f https://download.pytorch.org/whl/torch_stable.html

向听数问题

image
Mortal对于14张手牌的情况似乎是按照摸牌前的手牌来计算向听数的,导致如图中的情况第一次摸到听牌的时候仍然显示的是1向听。

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.