-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
281 changed files
with
9,984 additions
and
46,263 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,6 @@ | ||
node_modules | ||
.env | ||
play-log-*.log | ||
!logs | ||
docs/*.aux | ||
docs/*.log | ||
docs/*.synctex.gz | ||
docs/*.pdf |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
Hi, and thank you for caring about the game enough to click the "new issue" button because you wanted to report a bug, or have some feedback! | ||
|
||
If you have some feedback, then just start typing away and we can start a conversation (long or short, depending on what's necessary, of couse), but if you think you found a bug, there are some extra steps required, because in order to track down your bug I'll need to try to recreate the game as it was when you into the bug so: | ||
|
||
Try to describe your bug in steps: | ||
|
||
1. what was the game situation, | ||
2. what did you want to do, | ||
3. what thing, or sequence of things, did you do in order to achieve that | ||
4. what happened instead? | ||
|
||
Of course, sometimes a bug can be because the computer did something unexpected: | ||
|
||
1. what was the game situation | ||
2. what happened that was perfectly normal | ||
3. what then happened that was strange, or even wrong? | ||
4. what would you have expected to have happen insead? (and "nothing special" is a perfectly valid expectation!) | ||
|
||
If you have screenshots, those help a lot, and if you're a bit of a developer yourself, or you know what "the dev console" is and you've used it before, you might even consider playing with the `debug` flag turned on in the game settings, which will allow you to paste gameplay information in your bug reports. | ||
|
||
Thank you for your interest in the game, and hopefully together we can make it even better! |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
The moral right of the author has been asserted. | ||
|
||
All rights reserved, with the following exceptions: | ||
|
||
1. Permission is granted to copy these files for personal use only. | ||
|
||
2. No permission is granted to redistribute personal copies of these files. | ||
|
||
3. No permission is granted to rehost these files as a web page, including through "gh-pages" hosting effected when forking this project. | ||
|
||
4. Permission is granted to make offline modifications of any of these file. | ||
|
||
5. Permission is granted to make modified files publically accessible only for as long as is required to fascilitate submitting those modifications for inclusion in the original files. | ||
|
||
6. No permission is granted to make modified files publically accessible, or leave files made publically accessible, outside of the context specified in point (5). | ||
|
||
This license will be in effect until development has completed, at which time a more appropriate licese will be put in place. Completion is determined at the discretion of the author. | ||
|
||
Any exceptions to this license may be granted upon request. | ||
|
||
Clarification of this license may be provided upon request. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,62 +1,47 @@ | ||
# A Mahjong client/server project. | ||
# Mahjong. In the browser. | ||
|
||
![screenshot 311](https://cloud.githubusercontent.com/assets/177243/15599542/c5f1087e-2398-11e6-89e8-11ca62b2a17f.png) | ||
1: We're talking real four player mahjong here. Not the one player solitair game. That "game" has literally nothing to do with mahjong. | ||
|
||
This repository contains a client/server implementation for playing networked [Mahjong](https://en.wikipedia.org/wiki/Mahjong), using web sockets to connect each player to the server, specifically relying on [socket.io](http://socket.io). | ||
2: This README.md has been kept sparse pending a set of full length development articles that walk through going from "having an idea" to "having finished writing a fully functional game". | ||
|
||
And for those who think mahjong is a single-player tile matching game: it's not. It's a four player competitive game around forming high-scoring tile combinations with limited [common knowledge](https://en.wikipedia.org/wiki/Common_knowledge_%28logic%29) as well as [imperfect information](https://en.wikipedia.org/wiki/Perfect_information) local for each player. | ||
### Can I play this game? | ||
|
||
## Running things | ||
You sure can! And you don't even need to sign up for anything, or check out any programming code, or do anything beyond just clicking through to the live website: https://pomax.github.io/mj | ||
|
||
You'll need a modern version of [Node.js](https://nodejs.org) to run this project (as this project uses ES6 in lots of places), which at this point I kind of expect everyone has installed anyway. If not, install that first. You'll also need [`git`](https://git-scm.com), of course, but you're looking at a project on github so that part shouldn't have needed mention. | ||
Note that mostly due to "that's what we play in our house a lot", this implementation currently comes with "Chinese Classical" and "Cantonese" rules for play and scoring. Additional rules may eventually be written up, but if you want to get ahead of the game and implement one so it can be added to the repo, those will be more than welcome. | ||
|
||
With Node.js installed, the simplest way to run things is to `git clone` this repo, run `npm install` in the `./mahjong` dir that makes (to get all the dependencies installed), and to then run `npm start` in the same dir to start up both the server (which runs from `./src/server/server.js`) and run a live-compile for the web client (compiled using the webpack config in `./src/client/web`). | ||
### What it looks like | ||
|
||
- The server will run as game host on [http://localhost:8081/](http://localhost:8081) | ||
- The client is served on [http://localhost:8081/client](http://localhost:8081/client) | ||
![A screenshot of what the live game looks like when set to autoplay](https://user-images.githubusercontent.com/177243/53316594-5767d200-387d-11e9-86e2-ed8957d7feb2.png) | ||
|
||
Connecting to [http://localhost:8081/](http://localhost:8081) will give you a link to open the client. | ||
### This is a pure HTML, CSS, and JavaScript game | ||
|
||
## Release status | ||
That means there are no bundlers, no web app packaging, no CSS preprocessors or JS transpiling, just an index.html, a bunch of CSS files, and a bunch of JS files. If you can load the page, you now have a full copy of the game that you can save to your desktop and congratulations, you now have your own copy "installed" without doing anything beyond just downloading the page and its local page assets. | ||
|
||
**status: close to alpha release** | ||
I can hear the web devs amongst you thinking "but... then isn't it horribly inefficient?" to which I'm just going to point out that this is how we used to write the web and it was, and still is, blazing fast. This game has a [Google PageSpeed ranking of 97/98](https://developers.google.com/speed/pagespeed/insights/?url=https%3A%2F%2Fpomax.github.io%2Fmj%2F), so: don't be fooled (or, don't fool yourself) into thinking everything needs to be a web app bundle to be performant. | ||
|
||
This is a work in progress, so there's plenty that doesn't work right now, hopefully I can take this line out of the README.md in the near future. | ||
### Debugging using query parameters | ||
|
||
## License? | ||
Open `index.html` in your browser. Debugging options are set via URL query parameter, however, the way to toggle these is via the settings menu. | ||
|
||
While this code is being developed, everything in this repository is "all rights reserved". You have permission to clone this repo to run the code, but you can't modify and then redistribute the code, and you most certainly aren't permitted to run the code and make that accessible to the world at large. | ||
![A screenshot of the settings menu](https://user-images.githubusercontent.com/177243/54255517-a9635580-4515-11e9-8988-0520214e9a52.png) | ||
|
||
These restrictions will be greatly relaxed once the code gets closer to "releasable" state. | ||
### Node based testing | ||
|
||
## Contributing | ||
Most of the code is aware of whether it's running in the browser, or in node context. As such, the following things work: | ||
|
||
If you want to help improve this codebase, or add things you feel are missing: hurray! There's a few obvious places to start looking. | ||
- `node src/js/test/hand-generator` generates all possible hand patterns (based on tile category, not tile face) | ||
- `node src/js/core/algorithm/tiles-needed.js` runs unit tests | ||
- `node src/js/core/scoring/chinese-classical.js` runs unit tests | ||
|
||
### reporting bugs | ||
And for full gameplay debugging through play recordings, you can use `node src/js/test/play-game` with the following optional flags: | ||
|
||
Did you find a bug and want to report it? That's great! There will always be bugs that haven't been found by thosse writing the code, and hearing from you when you run into one is super valuable in terms of improving things for everyone. Take a screenshot, describe what was happening when you saw the bug manifest, and let's get that bug squished! | ||
- `-s <number>` the initial seed value for the pseudo-random number generator (defaults to 1). | ||
- `-r <number>` the number of games to play, bumping the seed up by 1 for each new game (defaults to 1). | ||
- `-nw` do **n**ot **w**rite a game log file upon finishing a game (defaults to writing log files). | ||
- `-cc` use the Chinese Classical ruleset (default ruleset). | ||
- `-cn` use the Cantonese ruleset. | ||
|
||
### tile sets | ||
### I have (a) question(s)! | ||
|
||
You can never have too many nice looking tiles, so if you have an MJ set that you particularly like and want to have your tiles added to the game, have a look at the `./apps/client/web/images/tiles` directory. | ||
|
||
### new play rules | ||
|
||
Everyone has their own play rules, and even as "officially recognized" rule sets, there are lots and lots, so if you want to help write a new ruleset, or implement one that you know of from other games (digital or real life), have a look at the `./apps/server/lib/game/rulesets` directory. If you want to just see how things work, have a look at the `minimal` ruleset for inspiration, and if you want to do any testing: remember to *rig the wall*: the `./apps/server/lib/game/wall.js` file comes with a commented off function that can be used to set up the wall exactly the way you want it to, so that you can start a game set up to do whatever you need in a single click. It saves a lot of testing time! | ||
|
||
### UI improvements | ||
|
||
It's extremely hard to come up with the perfect UI, so I like to take the "does it work at least a little? great, let's use that and then improve it as time goes on" approach. As such, the UI is certainly not stellar right now, but does allow all the functions you might need out of playing the game. However, you might be *much* better at UI design than I am, so if you have some good ideas and want to show mockups of what would be a better interface for players to both play the game and engage with each other (through a lobby, or ingame chat, etc), then your input is just as important as developer work on the code. | ||
|
||
### Documentation | ||
|
||
Do you want to help build out the documentation around both playing mahjong using this client/server implementation or just the game in general? That's great! When you write good docs *everybody wins*, so do get in touch and you can get your write on! | ||
|
||
## Where to contribute | ||
|
||
We're doing all the work right here, on github. Hit up the [issue tracker](https://github.com/pomax/mahjong/issues), which is emphatically **not** a "bug tracker", but a tracker of whatever issues are relevant to a project, covering all the above-mentioned points, and just start a new issue if you want to jump into this project. | ||
|
||
### Is there a CLA? | ||
|
||
No, there is not, but there is also no personal credit for specific parts of the code or its assets: by contributing to this project, your contributions become part of the project, and every contributor is valued equally. The contributor list is also based on your github name, not your real world name, unless you specifically also want that in the contributor list. Any legal complications (for instance, contributing code you did not have the rights to) are resolve based on the commit history: offending contributions will be reverted, and like normal human beings we'll find a way to make what you wanted to contribute can be done without breaking the law. | ||
I'd be happy to answer them! Feel free to [tweet at me](https://twitter.com/TheRealPomax) for shallow engagement, or file an issue over on [the issue tracker](https://github.com/Pomax/mj/issues) if you need deeper engagement. |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# Implementing Mahjong | ||
|
||
This article started off as a series of [jsbin](https://jsbin.com) links on twitter that went from implementing a mahjong table using CSS to a working multi-player game of mahjong, and it turns out that as fun as that was, wrapping the iterations in an article that talks about the process of going from "nothing" to "multiplayer online game implementation" is actually kind of educationally useful, so let's look at how to implement the game of mahjong (the real one, not the "mahojng solitaire" thing) by starting small, and building it out one bit at a time until we have a game that we could, in theory, package up and put on an app store somewhere. | ||
|
||
## So what is Mahjong? | ||
|
||
> _"It's basically a draw 1, play 1 game."_ | ||
> —Pomax | ||
It's usually a good idea to explain the thing we're going to try to achieve, which in this case means explaining what kind of game Mahjong actually is. | ||
|
||
At its core, Mahjong is a four player card game—except the cards are physical chunks of material and much smaller than a playing card, and they're called tiles—where all players start with a certain number of tiles, and then take turns drawing a tile, seeing if they now have a winning tile pattern, and if not, pick one of their tiles to discard before it's the next player's turn. | ||
|
||
Of course, the deck is slightly different from a standard card deck. For starters, there are 144 tiles, so let's discuss what our play resource looks like. | ||
|
||
There are three categories of tiles: | ||
|
||
1. numbered tiles, in three suits, | ||
2. unnumbered tiles, in two suits, and | ||
3. bonus tiles, with each suited tile in the deck four times, and each bonus tile in the deck once. | ||
|
||
The numbered suits are numbers 1 through 9 with dot ornamentation, bamboo ornamentation and Chinese character ornamentation. The unnumbered suits (also called "honours") are: | ||
|
||
1. the "winds" suit, consisting the four cardinal directions (east/south/west/north), and | ||
2. the "dragons" suit, consisting of the "green", "red" and "white" dragon (at least, that's what they're called in English, so we'll roll with that for now). | ||
|
||
The bonus tiles consist of four "season" tiles and four "seasonal flower" tiles, and don't do anything other than "get you free points" if you happen to draw certain ones, and you don't use them to form tile patterns with (you just put them aside and grab a replacement tile for it. If that's also a bonus tile, repeat). | ||
|
||
In fact, if you have a font with wide enough Unicode support, you should be able to see what these tiles look like because all these tiles have their own Unicode points: | ||
|
||
- dots 1 through 9: 🀙🀚🀛🀜🀝🀞🀟🀠🀡 | ||
- bamboo tiles: 🀐🀑🀒🀓🀔🀕🀖🀗🀘 | ||
- character tiles: 🀇🀈🀉🀊🀋🀌🀍🀎🀏 | ||
- winds: 🀀🀁🀂🀃 | ||
- dragons: 🀅🀄🀆 | ||
- seasons: 🀦🀧🀨🀩 | ||
- flowers:🀢🀣🀤🀥 | ||
|
||
We could use those in our implementation, but I prefer to play with "real" tiles, so let's instead use all the tiles as found over on https://github.com/Pomax/MJJS/tree/gh-pages/public/tiles because I just like them better. Probably because they are literally the tiles I have sitting on our games shelf. | ||
|
||
![https://raw.githubusercontent.com/Pomax/MJJS/gh-pages/public/tiles/39.jpg](https://raw.githubusercontent.com/Pomax/MJJS/gh-pages/public/tiles/38.jpg) ![https://raw.githubusercontent.com/Pomax/MJJS/gh-pages/public/tiles/39.jpg](https://raw.githubusercontent.com/Pomax/MJJS/gh-pages/public/tiles/39.jpg) ![https://raw.githubusercontent.com/Pomax/MJJS/gh-pages/public/tiles/39.jpg](https://raw.githubusercontent.com/Pomax/MJJS/gh-pages/public/tiles/40.jpg) ![https://raw.githubusercontent.com/Pomax/MJJS/gh-pages/public/tiles/39.jpg](https://raw.githubusercontent.com/Pomax/MJJS/gh-pages/public/tiles/41.jpg) | ||
|
||
In fact, we can even turn those tiles into a dedicated OpenType font with SVG colour glyphs, and add that to our game code once we're done, so we don't need to load tons of tiny images as loads of separate downloads. But now we're getting ahead of ourselves: I think it's time we started writing some code. | ||
|
||
|
||
- https://jsbin.com/cujapasese/2/edit?html,css,js,output (css variables) | ||
- https://jsbin.com/yituteboje/1/edit?css,output (tiles, click to discard) | ||
- https://jsbin.com/xuwuwajode/35/edit?js,output (basic sync pung-only play) | ||
- https://jsbin.com/weqilisiqi/7/edit?js,output (mildly improved sync play) | ||
- https://jsbin.com/kubuweravu/5/edit?js,output (async play) | ||
- https://jsbin.com/zimuzufoco/1/edit?js,output (async with a Player class) | ||
- https://jsbin.com/yenobexiku/6/edit?js,output (async claim and discard) | ||
- https://jsbin.com/yawenuyufi/2/edit?html,output (human play enabled) | ||
- https://jsbin.com/mapoxuwata/1/edit?js,output (chows enabled) | ||
- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
\documentclass[11pt,a4paper]{article} | ||
|
||
\usepackage{fontspec} | ||
\setmainfont{Candara} | ||
|
||
\begin{document} | ||
This is a test. | ||
\end{document} |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Binary file added
BIN
+354 KB
...ndscape_painting_in_the_Chinese_style_by_Shûgetsu,_Honolulu_Academy_of_Arts.jpg
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
This image is in the public domain in countries that respect the public domain, and that's good enough for me. | ||
|
||
See https://commons.wikimedia.org/wiki/File:Landscape_painting_in_the_Chinese_style_by_Sh%C3%BBgetsu,_Honolulu_Academy_of_Arts.jpg for more information. | ||
|
Diff not rendered.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.