Having recently acquired a Mah Jong set I have been playing Mah Jong recently and found scoring hands to be quite a chore, especially if you are bad at math like myself.
Here is a simple program that will score hands in Mah Jong. It wont score special hands properly though since they are limit/half limit hands anyways.
edit: I have changed the code to add action listeners to all the boxes and combo boxes. Having to press "calculate score" all the time is really annoying on a laptop
//Fri Dec 14 21:21:25 NZDT 2012
//Sat Dec 15 08:12:52 NZDT 2012 - Added action listener to everything
/*Below is the input used to generate this code
JPanel panel
*/
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.*;
import java.awt.*;
import javax.swing.event.*;
import java.awt.event.*;
import java.util.Scanner;
import java.util.ArrayList;
import java.text.NumberFormat;
import javax.swing.border.Border;
import java.util.*;
import java.io.*;
public class MahJongScorePanel extends JPanel implements ActionListener,KeyListener{
protected final String[]types={"Suit","Honour"};
protected final JCheckBox[]boxes=new JCheckBox[4];
protected final JFormattedTextField txtScore=new JFormattedTextField(NumberFormat.getIntegerInstance());
protected final JButton btnScore=new JButton("Calculate Score");
protected final Border blackline=BorderFactory.createLineBorder(Color.black);
protected final JFormattedTextField txtMisc=new JFormattedTextField(NumberFormat.getIntegerInstance());
protected final String[]sets={"Pung","Kong","Run"};
protected final JPanel[]setPanels=new JPanel[4];
protected final JComboBox[]boxSets=new JComboBox[setPanels.length];
protected final JComboBox[]boxTypes=new JComboBox[setPanels.length];
protected final JCheckBox boxMahJong=new JCheckBox("Mah Jong",true);
protected final JCheckBox boxPurity=new JCheckBox("Purity",false);
protected final JCheckBox boxOwnWind=new JCheckBox("Own Wind",false);
protected final JCheckBox boxRoundWind=new JCheckBox("Round Wind",false);
public static final String[]FILE_DIRECTORIES={"dot/","char/","bamb/","drag/","wind/"};
public static final LinkedHashSet<String>SPECIAL_TILES=new LinkedHashSet<String>(Arrays.asList(new String[]{
"Plum","Orchid","Chrysanthemum","Bamboo",
"Winter","Summer","Autumn","Spring"}));
public MahJongScorePanel(){
setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
setSize(800,300);
for(int i=0;i<setPanels.length;i++){
JPanel panel=new JPanel();
panel.setLayout(new BoxLayout(panel,BoxLayout.X_AXIS));
panel.add(new JLabel("Set Type (3/4/Run)"));
boxSets[i]=new JComboBox(sets);
boxSets[i].addActionListener(this);
panel.add(boxSets[i]);
boxes[i]=new JCheckBox("Concealed",false);
boxes[i].addActionListener(this);
boxes[i].setBorder(blackline);
panel.add(boxes[i]);
JLabel lbl=new JLabel("Suit or Honours");
lbl.setBorder(blackline);
panel.add(lbl);
boxTypes[i]=new JComboBox(types);
boxTypes[i].addActionListener(this);
panel.add(boxTypes[i]);
setPanels[i]=panel;
add(setPanels[i]);
}//4
JPanel pnl1=getPanel(true);
btnScore.addActionListener(this);
pnl1.add(btnScore);
pnl1.add(boxMahJong);
pnl1.add(new JLabel("Extra Points"));
txtMisc.setValue(0);
boxPurity.addActionListener(this);
boxOwnWind.addActionListener(this);
boxRoundWind.addActionListener(this);
pnl1.add(txtMisc);
pnl1.add(boxPurity);
pnl1.add(boxOwnWind);
pnl1.add(boxRoundWind);
add(pnl1);
JPanel tmpPnl=new JPanel();
tmpPnl.setLayout(new BoxLayout(tmpPnl,BoxLayout.X_AXIS));
tmpPnl.add(new JLabel("Total Score:"));
txtScore.setEditable(false);
tmpPnl.add(txtScore);
add(tmpPnl);
btnScore();
}//c
protected JPanel getPanel(boolean layout){
JPanel tmpPnl=new JPanel();
if(layout)tmpPnl.setLayout(new BoxLayout(tmpPnl,BoxLayout.X_AXIS));
else tmpPnl.setLayout(new BoxLayout(tmpPnl,BoxLayout.Y_AXIS));
return tmpPnl;
}
public void actionPerformed(ActionEvent ae){
// if(ae.getSource().equals(btnScore))btnScore();
btnScore();
}//actionPerformed
protected void btnScore(){
int score=0;
try{
score+=(Long)txtMisc.getValue();
}catch(Exception zerostart){}
int doubles=0;
if(boxMahJong.isSelected())score+=20;
for(int i=0;i<setPanels.length;i++){
int runScore=0;
if(boxSets[i].getSelectedIndex()==0)runScore=2;
if(boxSets[i].getSelectedIndex()==1)runScore=4;
if(boxTypes[i].getSelectedIndex()==1){
runScore*=2;
doubles++;
}//fi
if(boxes[i].isSelected())runScore*=2;
score+=runScore;
}//4 panels
if(boxPurity.isSelected())doubles++;
if(boxOwnWind.isSelected())doubles++;
if(boxRoundWind.isSelected())doubles++;
for(int i=0;i<doubles;i++){
score*=2;
}
txtScore.setValue(score);
}//btnScore
public void keyPressed(KeyEvent e){
int key=e.getKeyCode();
if(key == KeyEvent.VK_LEFT || key == KeyEvent.VK_NUMPAD4){
}//if you press left
if (key == KeyEvent.VK_RIGHT || key == KeyEvent.VK_NUMPAD6){
}//right
if(key == KeyEvent.VK_UP || key == KeyEvent.VK_NUMPAD8){
}//if you press up
if(key == KeyEvent.VK_DOWN || key == KeyEvent.VK_NUMPAD2){
}//down
}
public void keyReleased(KeyEvent e){
}
public void keyTyped(KeyEvent e){
if(e.getKeyChar() == 27){
System.exit(0);
}//esc
if(e.getKeyChar() == KeyEvent.VK_ENTER){
}
}//me keys
public static void main(String[]args){
JFrame frame=new JFrame("Mah Jong Score Panel by Tiwa Pene Fri Dec 14 22:32:42 NZDT 2012");
MahJongScorePanel scorepanel=new MahJongScorePanel();
frame.add(scorepanel);
frame.setSize(scorepanel.getSize());
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
frame.setVisible(true);
}//main
}//class
The only actual java mah jong game (not that idiot solitaire version) I have found that is any good is this one:
edit: Whoops, messed up the link. Its missing a quotation mark
Mythosware Mah-Jong v1.0 (http://mythosware.blogspot.co.nz/2010/05/mah-jong-v10.html)
------------------------
(C) Andrew Lawrenson 2010
http://www.mythosware.co.uk
Unfortunately the resolution to play it is something like 1400xsomething stupid which does nothing for the game.
p.s I have been working on Java Mah Jong since finding the previous one to be an unsuitable resolution, hence the screenshot from The Monopoly Thread (http://www.getsome.co.nz/showthread.php?84089-Monolopy!&p=1511030&viewfull=1#post1511030) which is a modified Mah Jong layout.
When you say hard scoring do you mean remembering all the possible special hands? Quite like the proper game but takes a while if there's only one manual. Programming the AI would be interesting.
Special Hands only score 500,1000,1500, or 2000 and half that when Fishing.
Depending on what rules you are using (British, American, Chinese, Japanese, Cantonese) the special hands are different.
Scoring special hands is easy, because they only have one way of appearing which gives you a Map of possible tile combinations. e.g
Nothing Connects has a set arrangement of tiles as does Great Jade Hand.
These hands get scored to the 'limit' (usually 1000) or half limit (500). When you are playing for money, it is usually no limit. If you are playing for lollies, then it is DEFINITELY no limit! Usually: 1 lolly = 10 points so a limit hand means most other players will probably have to pay you 100 lollies. YAY DIABETES!
The scoring is just for a 'normal' hand, which is annoying to do. Oh! Since we have Pyromanik here who does know how to play, I might as well post up the rules :D
Mah Jong: Easy to play
If you've played Gin Rummy, Rummy, Five Hundred, or Bridge then you most certainly know how to play Mah Jong, because it is the game the Card Games originated from.
Mah Jong is pretty easy to learn how to play. A Mah Jong set consists of 136 tiles, but most sets have 144 tiles (4 seasons, 4 flowers). In Mah Jong there are three 'suits' of tiles
Bamboo
Characters
Circles (Actually 'Coins' in Cantonese/Chinese)
Each of these tiles are numbered 1 to 9. There are four of every tile.
There are also two 'honour' type tiles:
Winds: East, West, North, South
Dragons: Red, Green, White (usually a blank tile)
There are four of each of these tiles too.
Mah Jong: Players Hands
In Mah Jong you need four players for a proper game.
Each Player has a hand of thirteen (13) tiles. To win you have to declare Woo/Mah Jong by drawing a winning tile or picking up another players discarded tile.
The simplest way to go Mah Jong is as follows:
four sets of three tiles (either 3 of a kind OR a run (1,2,3/2,3,4/5,6,7 etc)) (twelve (12) tiles in total)
A pair (making fourteen (14) tiles)
There are 'special' hands which I will ignore for now.
Mah Jong: How rounds work
At the start of the game each player is assigned a Wind (North, South, East, West) which follows naturally from the Never Eat Sour Watermelons order.
Depending on what rules you are playing, there is also a 'Prevailing Wind' which I will explain later.
East Wind is always the Dealer (Also Prevailing Wind at the beginning of a game). East Wind draws first. East Wind always gets PAID DOUBLE, but also LOSES DOUBLE if they dont go Mah Jong.
Play goes in Order (East, South. West, North). Each player draws a tile to make a hand of 14 tiles, but then must discard a tile.
All discarded tiles go in the center of the table.
ANY PLAYER may declare "PUNG!"(3 of a kind), "KONG!"(four of a kind),"CHOW!"(a run), or Mah Jong and pick up the discarded tile.
Then THAT PLAYER must reveal their set/run and discard a tile (unless they went Mah Jong)
When sets/runs are Revealed, they are placed FACE UP in front of the player to show the other players what that player has.
If a player picks up a discarded tile, then play continues from that player. In intense Mah Jong games, players can miss several goes and not even get the opportunity to go Mah Jong.
The order of precedence for tiles works as follows (highest priority to lowest): Mah Jong, Kong, Pung, Chow. IF there is a tie (two people go Mah Jong) then the player who is next in line of turn gets precedence (Chinese Rules)
SPECIAL - If a player has a Four of a kind then they must draw an extra tile from the "Dead Wall", but if not playing with a Dead Wall (simplified rules) then simply take a tile from the END OF THE WALL, not from the normal draw end.
Mah Jong: Scoring
This is where my little program comes in. Scoring is very easy, but can be time consuming when a big hand is played.
These are the 'simplified' rules for scoring, proper Cantonese/Gambling rules can be quite complex because once money is involved, all morality goes out the window.
Pung (3 of a kind): 2 points
Kong (4 of a kind): 4 points
Chow (run): 0 points
Revealed: normal
Concealed: points*2 (Concealed is when you make a set without having picked up a discarded tile/forced to reveal)
Honours Tiles (Dragons or Winds): points*2 (+1 double)
Going Mah Jong +20
(Simplified rules do not use the special points for 1/9 of suits which are worth double)
For example: A pung of two (2) of bamboo would net you 2 points if revealed, 4 points if concealed, but a pung of Green Dragons would get you 4 points revealed and 8 points of concealed (plus a double which I will explain later)
Mah Jong: Scoring Doubles
This is where the fun begins. In special cases, your score can be doubled. As I mentioned before, for each pung/kong of honour tiles you get to double your total overall score.
Other ways are:
Pung/Kong of own Wind: +1 double
Pung/Kong of prevailing Wind: +1 double
Purity (One suit only + Dragons/Winds): +1 double
Purity (One suit, no winds, no dragons): +2 doubles (or +3 doubles, I forget)
Dont forget that EAST WIN PAYS DOUBLE/WINS DOUBLE
Mah Jong: Limit Hands
As you may realise, some hands will have an absolute mammoth score. Anything over 128 points is 'unusual', anything over 200 points is a very good hand.
Anything over 1000 points means everyone else goes home broke.
e.g Hand consists of 4*East Wind concealed + 3*Red Dragon Revealed+3*Green Dragon Revealed + 4*West Wind revealed + White Dragon Pair
8 points (+1 double) + 4 points (+1 double) + 4 points (+1 double) + 16 points (+1 double) + 20 Mah Jong
32 + 20 = 52 points
52*2*2*2*2 = 3328 (which is well above the limit)
Oh yeah, I forgot: East Wind means everyone pays you double.
People would never play with you again
Mah Jong: Scoring What is so hard about that?
Well: When you go Mah Jong, everyone pays the 'winner'/Mah Jonger (who may not actually be the 'winner' at all)
Each player scores their hand and they PAY THE DIFFERENCE BETWEEN THEIR HAND AND THE WINNERS HAND
This means a person can have a better hand than the person who won, which depending on the rules means that:
a) The Mah Jong player pays that person the difference in their scores (in a serious game)
b) The player does not have to pay the Mah Jong player anything (usual rule)
This also means that a person who has nothing in their hand at the end pays the most.
This also means that being EAST WIND (the Dealer) can be a blessing or a curse (much like "Clubs Compulsary" in Euchre).
Mah Jong: Conclusion
I've found that people who hate card games LOVE Mah Jong because the Tiles are more tactile and its alot more interactive ('stealing' peoples turns or even better: The tiles they need) plus, if you play with Cantonese people, the smack talk never stops.
(spoiler contains picture of Java Game thing I am making)
(http://www.getsome.co.nz/attachment.php?attachmentid=7632&stc=1&d=1355528434)