?? 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 + -