📄 handbone.java
字号:
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
//手中的牌
public class HandBone {
private Bone m_aGangBone[]; //明杠过的牌
private int m_nGang; //明杠过的牌的个数
private Bone m_aAnGangBone[]; //暗杠过的牌
private int m_nAnGang; //暗杠过的牌的个数
private Bone m_aChiBone[]; //吃过的牌
private int m_nChi; //吃过的牌的个数
private Bone m_aPengBone[]; //碰过的牌
private int m_nPeng; //碰过的牌的个数
private Bone m_aHandBone[]; //手中的牌,经过吃碰杠剩下的牌
private int m_nHand; //手中牌的个数
private Bone m_HoldBone; //摸到的牌
private Image m_ArrowImg;
private int m_nSelectIndex; //打牌的位置
private int m_aChiIndex[]; //可以吃的牌的索引数组
//m_nChiIndex是m_aChiIndex中当前选择的索引,因为可能同时存在几种吃法
private int m_nChiIndex;
private int m_aPengIndex[]; //可以碰的牌的索引数组
private int m_aGangIndex[]; //可以杠牌的的索引数组
private int m_aAnGangIndex[]; //可以暗杠牌的的索引数组
private int m_nX; //牌起始位置的X坐标
private int m_nY; //牌起始位置的Y坐标
private boolean m_bPlayer; //true表示为玩家的牌,false表示电脑的牌
//构造方法
//参数arrow为箭头图像
//参数x、y为牌起始位置
//参数bPlayer为true表示为玩家的牌,为false表示电脑的牌
public HandBone( Image arrow, int x, int y, boolean bPlayer ){
m_nX = x;
m_nY = y;
m_ArrowImg = arrow;
m_aGangBone = new Bone[16]; //最多有16张名杠
m_aAnGangBone = new Bone[16]; //最多有16张暗杠
m_aChiBone = new Bone[12]; //最多有12张牌被吃
m_aPengBone = new Bone[12]; //最多有12张牌被碰
m_aHandBone = new Bone[13]; //手中最多有13张牌
m_aChiIndex = new int[6]; //用3组,每组2个数据记录手中与桌面上可组成吃牌的索引
m_aPengIndex = new int[2]; //手中与桌面上可组成碰牌的索引
m_aGangIndex = new int[3]; //手中与桌面上可组成杠牌的索引
m_aAnGangIndex = new int[3]; //手中与桌面上可组成暗杠牌的索引
m_bPlayer = bPlayer;
Reset();
}
//获取是否是玩家的牌的标志
public boolean isPlayer(){
return m_bPlayer;
}
//重新开牌
public void Reset(){
for( int n = 0; n < 16; n ++ ){
m_aGangBone[n] = null;
m_aAnGangBone[n] = null;
if( n < 13 )
m_aHandBone[n] = null;
if( n < 12 ){
m_aChiBone[n] = null;
m_aPengBone[n] = null;
}
}
m_HoldBone = null;
m_nGang = 0;
m_nAnGang = 0;
m_nChi = 0;
m_nPeng = 0;
m_nHand = 0;
}
//向手中增加牌
public boolean AddHandBone( Bone bone ){
if( m_nHand >= m_aHandBone.length )
return false;
m_aHandBone[m_nHand] = bone;
if( m_bPlayer )
m_aHandBone[m_nHand].setState(Bone.BASE_FRONT);
else
m_aHandBone[m_nHand].setState(Bone.BASE_BACK);
m_nHand ++;
return true;
}
//摸牌
public void SetHold( Bone bone ){
m_HoldBone = bone;
m_nSelectIndex = m_nHand;
}
//获取刚摸到的牌
public Bone getHoldBone(){
return m_HoldBone;
}
//移动选择的位置,参数bLeft为true表示向左移动,否则向右移动
public void MoveSelect( boolean bLeft ){
int index = m_nSelectIndex;
if( bLeft )
index --;
else
index ++;
if( index < 0 )
index = m_nHand;
if( index > m_nHand )
index = 0;
//要打的牌的位置,index为m_nHand表示要打刚刚摸到的牌
//index为0~m_nHand-1时为打手中剩余的牌
m_nSelectIndex = index;
}
//打出牌,参数index为手中牌的索引
//返回打出的牌
public Bone OutBone(){
//还没摸牌则不能打牌
if( m_HoldBone == null )
return null;
if( m_nSelectIndex < 0 || m_nSelectIndex > m_nHand )
return null;
Bone bone;
if( m_nSelectIndex == m_nHand )
bone = m_HoldBone; //打摸到的牌
else
{//打手中其他的牌,并将摸到的牌放到手中
bone = m_aHandBone[m_nSelectIndex];
m_aHandBone[m_nSelectIndex] = m_HoldBone;
}
m_HoldBone = null;
OrderHand(); //排列手中牌的顺序
return bone;
}
//排列手中剩余牌的顺序
public void OrderHand(){
Bone temp;
for( int i = 0; i < m_nHand; i ++ )
{
for( int j = i + 1; j < m_nHand; j ++ )
{
if( m_aHandBone[i].getWord() > m_aHandBone[j].getWord() )
{//先按类型排列
temp = m_aHandBone[i];
m_aHandBone[i] = m_aHandBone[j];
m_aHandBone[j] = temp;
}
else if( m_aHandBone[i].getWord() == m_aHandBone[j].getWord() )
{//类型相同则按牌的面值排列
if( m_aHandBone[i].getValue() > m_aHandBone[j].getValue() )
{
temp = m_aHandBone[i];
m_aHandBone[i] = m_aHandBone[j];
m_aHandBone[j] = temp;
}
}
}
}
}
//判断手中的剩余牌与指定的牌是否可以组成“杠”,参数bone为指定的牌
public boolean canGang(Bone bone){
for( int n = 0; n < m_aGangIndex.length; n ++ )
m_aGangIndex[n] = -1;
//有三张面值及种类与bone相同的牌,则可以杠
int word = bone.getWord();
int value = bone.getValue();
int num = 0;
for( int n = 0; n < m_nHand; n ++ )
{
if( m_aHandBone[n].getWord() == word &&
m_aHandBone[n].getValue() == value )
{
if( num < m_aGangIndex.length ){
m_aGangIndex[num] = n;
num ++;
}
}
}
if( m_aGangIndex[2] != -1 )
return true;
//和已经名的碰牌杠
num = 0;
for( int n = 0; n < m_nPeng; n ++ ){
if( m_aPengBone[n].getWord() == word &&
m_aPengBone[n].getValue() == value ){
m_aGangIndex[num] = n + 100;
num ++;
}
}
if( m_aGangIndex[2] != -1 )
return true;
return false;
}
//判断手中的剩余牌与指定的牌是否可以组成“暗杠”,参数bone为指定的牌
public boolean canAnGang(Bone bone){
for( int n = 0; n < m_aAnGangIndex.length; n ++ )
m_aAnGangIndex[n] = -1;
//有三张面值及种类与bone相同的牌,则可以杠
int word = bone.getWord();
int value = bone.getValue();
int num = 0;
for( int n = 0; n < m_nHand; n ++ )
{
if( m_aHandBone[n].getWord() == word &&
m_aHandBone[n].getValue() == value )
{
if( num < m_aGangIndex.length ){
m_aAnGangIndex[num] = n;
num ++;
}
}
}
if( m_aAnGangIndex[2] != -1 )
return true;
return false;
}
//判断手中的剩余牌与指定的牌是否可以组成“碰”,参数bone为指定的牌
public boolean canPeng(Bone bone){
for( int n = 0; n < m_aPengIndex.length; n ++ )
m_aPengIndex[n] = -1;
//有两张面值及种类与bone相同的牌,则可以碰
int word = bone.getWord();
int value = bone.getValue();
int num = 0;
for( int n = 0; n < m_nHand; n ++ )
{
if( m_aHandBone[n].getWord() == word &&
m_aHandBone[n].getValue() == value )
{
if( num < m_aPengIndex.length ){
m_aPengIndex[num] = n;
num ++;
}
}
}
if( m_aPengIndex[1] != -1 )
return true;
return false;
}
//判断手中的剩余牌与指定的牌是否可以组成“吃”,参数bone为指定的牌
public boolean canChi(Bone bone){
for( int n = 0; n < m_aChiIndex.length; n ++ )
m_aChiIndex[n] = -1;
m_nChiIndex = 0;
//aShun存储手中与bone相连的牌的索引(前后能组成吃的最多5张牌)
//aShun[2]代表指定的牌如五万
//aShun[0]代表指定的牌的前2个面值的牌,如三万
//aShun[1]代表指定的牌的前1个面值的牌,如四万
//aShun[3]代表指定的牌的后1个面值的牌,如六万
//aShun[4]代表指定的牌的后2个面值的牌,如七万
int aShun[] = new int[5];
for( int n = 0; n < aShun.length; n ++ )
aShun[n] = -1;
int word = bone.getWord();
if( word == Bone.WORD_ZI )
return false;
int value = bone.getValue();
for( int n = 0; n < m_nHand; n ++ )
{
if( m_aHandBone[n].getWord() == word )
{
int index = m_aHandBone[n].getValue() - value;
if( index >= -2 && index <= 2 )
{//如果在可组成吃牌的范围内
aShun[index+2] = n;
}
}
}
boolean bReturn = false;
if( aShun[0] != -1 && aShun[1] != -1 )
{//存在第一种吃法,如有三万、四万吃五万
m_aChiIndex[0] = aShun[0];
m_aChiIndex[1] = aShun[1];
m_nChiIndex = 0;
bReturn = true;
}
if( aShun[1] != -1 && aShun[3] != -1 )
{//存在第二种吃法,如有四万、六万吃五万
m_aChiIndex[2] = aShun[1];
m_aChiIndex[3] = aShun[3];
m_nChiIndex = 2;
bReturn = true;
}
if( aShun[3] != -1 && aShun[4] != -1 )
{//存在第三种吃法,如有六万、七万吃五万
m_aChiIndex[4] = aShun[3];
m_aChiIndex[5] = aShun[4];
m_nChiIndex = 4;
bReturn = true;
}
return bReturn;
}
//移动能吃牌的种类的选择,参数bLeft为true表示向左移动,否则向右移动
public void MoveChiIndex( boolean bLeft ){
int index = m_nChiIndex;
if( bLeft )
index -= 2;
else
index += 2;
if( index >=0 && index < m_aChiIndex.length - 1 ){
if( m_aChiIndex[index] != -1 )
m_nChiIndex = index;
}
}
//判断手中的剩余牌与指定的牌是否可以组成“胡”,参数bone为指定的牌
public boolean canHu( Bone bone ){
//将指定的牌与手中的牌组成新的数组
Bone atemp[] = new Bone[m_nHand + 1];
for( int n = 0; n < m_nHand; n++ ){
atemp[n] = m_aHandBone[n];
}
atemp[m_nHand] = bone;
//Divide中会不断地拆分atemp中的牌,如果能拆出胡牌的结构则返回null
if( Divide( atemp, false ) == null )
return true;
return false;
}
//与指定的牌做“杠”牌操作,参数bone为指定的牌
//返回true表示操作成功
public boolean Gang( Bone bone ){
//m_aGangIndex数组存储手中能杠的牌的索引
int index1 = m_aGangIndex[0];
int index2 = m_aGangIndex[1];
int index3 = m_aGangIndex[2];
//保存杠牌
if( index1 > 100 ){
//与已经明的,成“碰”的牌进行“杠”
m_aGangBone[m_nGang] = bone;
m_aGangBone[m_nGang+1] = m_aGangBone[index1-100];
m_aGangBone[m_nGang+2] = m_aGangBone[index2-100];
m_aGangBone[m_nGang+3] = m_aGangBone[index3-100];
//将“碰”牌中的“杠”牌去掉
for( int n = 0; n < m_nPeng; n ++ ){
if( n == index1 || n == index2 || n == index3 ){
for( int m = n; m < m_nPeng-1; m ++ ){
m_aPengBone[m] = m_aPengBone[m + 1];
}
}
}
m_nPeng = m_nPeng - 3;
}
else{//与手中剩余的牌进行“杠”
m_aGangBone[m_nGang] = bone;
m_aGangBone[m_nGang+1] = m_aHandBone[index1];
m_aGangBone[m_nGang+2] = m_aHandBone[index2];
m_aGangBone[m_nGang+3] = m_aHandBone[index3];
}
m_nGang += 4;
//将手中“杠”掉的拍去掉
int num = 0;
for( int n = 0; n < m_nHand; n ++ )
{
if( n == index1 || n == index2 || n == index3 )
continue;
m_aHandBone[num] = m_aHandBone[n];
num ++;
}
m_nHand = m_nHand - 3;
m_nSelectIndex = m_nHand;
return true;
}
//与指定的牌做暗杠操作,参数bone为指定的牌
//返回true表示操作成功
public boolean AnGang( Bone bone ){
//m_aAnGangIndex数组存储手中能暗杠的牌的索引
int index1 = m_aAnGangIndex[0];
int index2 = m_aAnGangIndex[1];
int index3 = m_aAnGangIndex[2];
m_aAnGangBone[m_nAnGang] = bone;
m_aAnGangBone[m_nAnGang+1] = m_aHandBone[index1];
m_aAnGangBone[m_nAnGang+2] = m_aHandBone[index2];
m_aAnGangBone[m_nAnGang+3] = m_aHandBone[index3];
m_nAnGang += 4;
//将手中杠掉的拍去掉
int num = 0;
for( int n = 0; n < m_nHand; n ++ )
{
if( n == index1 || n == index2 || n == index3 )
continue;
m_aHandBone[num] = m_aHandBone[n];
num ++;
}
m_nHand = m_nHand - 3;
m_nSelectIndex = m_nHand;
return true;
}
//与指定的牌做吃牌操作,参数bone为指定的牌
//返回true表示操作成功
public boolean Chi( Bone bone ){
//m_aChiIndex数组存储能手中暗杠的牌的索引
int index1 = m_aChiIndex[m_nChiIndex];
int index2 = m_aChiIndex[m_nChiIndex+1];
m_aChiBone[m_nChi] = bone;
m_aChiBone[m_nChi+1] = m_aHandBone[index1];
m_aChiBone[m_nChi+2] = m_aHandBone[index2];
//对吃到的牌进行排序
for( int i = m_nChi; i < m_nChi + 3; i ++ ){
for( int j = i + 1; j < m_nChi + 3; j ++ ){
if( m_aChiBone[i].getValue() > m_aChiBone[j].getValue() )
{
Bone temp = m_aChiBone[i];
m_aChiBone[i] = m_aChiBone[j];
m_aChiBone[j] = temp;
}
}
}
m_nChi += 3;
//将手中吃掉的拍去掉
int num = 0;
for( int n = 0; n < m_nHand; n ++ )
{
if( n == index1 || n == index2 )
continue;
m_aHandBone[num] = m_aHandBone[n];
num ++;
}
m_nHand = m_nHand - 3;
m_nSelectIndex = m_nHand;
m_HoldBone = m_aHandBone[m_nHand];
return true;
}
//与指定的牌做碰牌操作,参数bone为指定的牌
//返回true表示操作成功
public boolean Peng( Bone bone ){
//m_aPengIndex数组存储手中能碰的牌的索引
int index1 = m_aPengIndex[0];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -