java麻将算法代码 麻将游戏编程算法

谁有Java 游戏编程开发教程这本书二人麻将游戏源代码或这本书的电子版String []mapimg={"source/font.png","source/ks.jpg","source/1.jpg","source/2.png",
"source/3.jpg","source/youknow.jpg","fight/js.jpg","fight/js1.jpg"};
//获得工具包
Toolkit tool=Toolkit.getDefaultToolkit()
//开始图片
Image startimg;
//背景图片
Image bjimg,fontimg;
//画开始界面
publicvoid drawstart(Graphics g){
startimg=tool.getImage(mapimg[1]);
g.drawImage(startimg, 0, 0, frame.getWidth(), frame.getHeight(), frame);
fontimg=tool.getImage(mapimg[0]);
g.drawImage(fontimg, 20, 30, frame);
}java麻将算法代码;
这是我以前做的一个很简单的游戏中的几行代码java麻将算法代码,对你的问题java麻将算法代码,你要手动选择图片java麻将算法代码,那做个文件选择器,把图片路径作为方法参数传进去就ok了
求一个麻将的出牌的算法思路(麻将人工智能),最好可以提供资料,本人感激不尽没接触过程序设计.不过我想:首先 你要知道麻将里的输赢规则,那些牌克制那些牌.然后监视玩家手里的牌,最后让AI针对玩家出牌就好.
因为麻将的张数很多,让AI直接出牌克制, 也让玩家不易察觉AI作弊.再次之,如果嫌AI设计体积太大了,可以让玩家得组合牌的几率降低.
当然,好不好玩,哪的另算
计算麻将的番数(C/Java)import java.util.Scanner;
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
String string=null;
Scanner cin = new Scanner(System.in);
while (cin.hasNext()){
string=cin.next();
}
String str[]=string.split(",");
int i=0;
int count=0;
if(str.length==7){
count=count 2;
}
else{
for(i=0;istr.length;i){
if(str[i].length()==6str[i].charAt(0)=='1'str[i].charAt(2)=='2'
str[i].charAt(4)=='3'str[i].charAt(1)=='T'
str[i].charAt(3)=='T'str[i].charAt(5)=='T'){
count=count 1;
}
else if(str[i].length()==8){
count=count 2;
}
}
}
System.out.println(count);
}
}
可以随配的那种麻将算法?将算法(上)
?、?将规则(云南昭通?将)
1.牌
1) “万”“筒”和“条”三房牌,各36张,共108张牌;
2) 只能 “碰”“杠”“胡”,不能吃牌
3) 4?进?游戏;
4) 游戏开始时,庄家摸14张牌,闲家摸13张牌;
5) 有4个癞?牌(坨牌:既可以作为本?牌型可以替换为任意牌)
2.游戏术语
1) 坎:???中有三张相同的牌;
2) 碰牌:???中有两张 , 别?再打出?张 , 则可以?两张去碰 , 并将这三张亮出来;
3) 明杠:???中有?坎,别?在打出?张 , 则可以?三张去杠,称之为明杠,所有的杠都是从牌墙前?补牌的 。
4) 暗杠:??摸到了四张相同的牌,则可以暗杠;
5) 补杠:??已经碰了的牌,???摸到了第4张 , 则可以补杠;
6) 根:??的?牌和碰牌中有四张相同的但是没杠下来的,称之为根;
7) 叫:即听牌,?户当前的13张牌 , 再摸?张牌就可以和牌的牌型;
8) 墙?:摸完牌后,翻出?张牌,放在下家的堆牌区中 。
9) 坨:摸完牌后,翻出牌墙第?张牌,定义为癞?牌 。
10) 满飞满杀:坨拿去杠 。
案例1:?上2个5条 , 有?打出5条,可以拿2个5条加1个坨去杠5条
案列2:已碰了3万,?上有坨 , 可以直接拿坨去杠3万
11) 飞碰:坨加?张单牌拿去碰的过程 。
12) 亮牌:胡牌后亮出所有牌(牌桌上的玩家都可以看),剩下的继续?战 。
3.胡牌规则
1) 胡牌条件:缺?门成牌型即可胡牌
缺?门:游戏开始后,必须打缺?门 , 中途可以换打缺哪门(不是定缺),胡牌局牌时必须只有2 门或1门(筒、万、条牌型)胡牌的基本牌型:
i. 11、123、123、123、123;
ii. 11、123、123、123、111/1111(下同);
iii. 11、123、123、111、111;
iv. 11、123、111、111、111;
v. 11、111、111、111、111;
vi. 11、22、33、44、55、66、77;
2) 牌型
牌型说明
棒棒正常普通的和牌,所谓的平胡
勾胡?上有杠的牌型
天胡庄家起?牌就和牌
地胡庄家打出的第??牌被闲家和
清??只有?种花?的牌型
杠上炮玩家杠了之后摸起来那张牌点的炮
【java麻将算法代码 麻将游戏编程算法】杠上花玩家杠了以后?摸,?论暗杠、明杠、加杠都相当于?摸抢杠和别?补杠的杠牌(不是补杠后摸得那张)
?对?11、111、111、111、111的牌型
巧七对11、22、33、44、55、66、77的牌型
龙七对11、22、33、44、55、6666的牌型
?、?将算法设计(?维数组形式)
1.类型定义(类型*10)
万 10 (万牌的张数)
11——19 ?万-九万
筒 20 (筒牌的张数)
21——29 1筒 - 9筒
条 30 (条?牌的张数)
31——31 1条 - 9条
风牌 40(?前?风牌)41——49 东南西北中发?
2.牌下标定义
(1)万字牌的对应
4张1万 11 11 11 11
4张2万 12 12 12 12
4张3万 13 13 13 13
4张4万 14 14 14 14
4张5万 15 15 15 15
4张6万 16 16 16 16
4张7万 17 17 17 17
4张8万 18 18 18 18
4张9万 19 19 19 19
3.初始化牌和发牌
1)把所有牌放到牌堆
/**
* 初始化?将
*
* @return
*/
public ListInteger initAllPai() {
ListInteger allPai = new LinkedList();
for (int i = 11; i40; i) {
if (i % 10 == 0) {
continue;
}
for (int j = 0; j4; j) {
allPai.add(i);
}
}
return allPai;
}
2)发牌,发四份牌
/**
* 发牌
* @param initAllPai
*/
public ListListInteger faPai(ListInteger initAllPai) { // 洗牌打乱顺序
Collections.shuffle(initAllPai);
ListListInteger paiLists = new ArrayList();
for (int j = 0; j4; j) {
ListInteger pais = new ArrayList();
for (int i = 0; i13; i) {
//从牌堆中移除?张牌
Integer remove = initAllPai.remove(0);
pais.add(remove);
}
paiLists.add(pais);
}
return paiLists;
}
3)把牌分成?维数组判断能否胡牌、杠牌、碰牌
/**
* 牌的类型?万-九万 11 - 19 ?筒-九筒 21 - 29 ?索-九索 31-39 将牌转换为?维数组
*
* ?位是牌型总数
*
* @param list
* @return
*/
public static int[][] changeToArr(ListInteger list) {
int[][] allPai = new int[4][10];
for (int i = 0; ilist.size(); i) {
Integer pai = list.get(i);
switch (pai / 10) {
case 1:
allPai[0][0] = allPai[0][0]1;
allPai[0][pai % 10] = allPai[0][pai % 10]1;
break;
case 2:
allPai[1][0] = allPai[1][0]1;
allPai[1][pai % 10] = allPai[1][pai % 10]1;
break;
case 3:
allPai[2][0] = allPai[2][0]1;
allPai[2][pai % 10] = allPai[2][pai % 10]1;
break;
case 4:
allPai[3][0] = allPai[3][0]1;
allPai[3][pai % 10] = allPai[3][pai % 10]1;
break;
default:
break;
}
}
return allPai;
}
4.测试效果
public static void main(String[] args) {
ListInteger initPais = initAllPai();
ListListInteger paiLists = faPai(initPais);
for (ListInteger pais : paiLists) {
System.out.println("everyone pais :"pais);
}
}
所有的牌:all pai:[[36,4,4,4,4,4,4,4,4,4],[36,4,4,4,4,4,4,4,4,4],[36,4,4,4,4,4,4,4,4,4],[0,0,0,0,0,0,0,0,0,0]]结果
该玩家牌为 :[13, 21, 25, 16, 24, 12, 24, 38, 27, 36, 36, 15, 39] 缺牌类型为:0
该玩家牌为 :[33, 36, 26, 34, 36, 39, 39, 38, 19, 21, 24, 35, 26] 缺牌类型为:0
该玩家牌为 :[17, 26, 17, 22, 11, 29, 37, 18, 31, 23, 11, 13, 28] 缺牌类型为:2
该玩家牌为 :[13, 33, 25, 11, 17, 31, 37, 37, 27, 15, 12, 11, 28] 缺牌类型为:1
三)?将业务算法
1)判断是否缺?门(只有筒、万、条中的?种或两种牌型)
/**
* 是否缺?门
* @param paiList 玩家?中所有牌
* @param tuopai 癞?牌
* @return
*/
public static boolean isQueYiMen(ListInteger paiList, int tuopai) { ListInteger allPais = new ArrayList(paiList);
allPais.remove(tuopai);
int[][] allPai = changeToArr(allPais);
if (allPai[0][0] == 0) {//万牌为0张
return true;
}
if (allPai[1][0] == 0) {//筒牌为0张
return true;
}
if (allPai[2][0] == 0) {//条牌为0张
return true;
}
return false;//三种牌都不缺
}
2)缺的牌类型下标
/**
* 缺的类型下标
* @param allPai
* @param tuopai
* @return
*/
public static int choseQueType(int[][] allPai, int tuopai) {
if (allPai[0][0] == 0) {//万牌为0张 , 即可返回,不?执?下?代码,提?运?效率 return 0;
}
if (allPai[1][0] == 0) {//筒牌为0张
return 1;
}
if (allPai[2][0] == 0) {//条牌为0张
return 2;
}
int yu = tuopai / 10 - 1;
int mod = tuopai % 10;
int num = allPai[yu][mod];//癞?牌的号码,癞?牌不算?种牌类型
int index = 0;
for (int count = 0; count2; count) {//遍历移除癞?牌三种类型牌的数量
int last = allPai[index][0];
int next = allPai[count1][0];
// 除去坨牌的数量
if (index == yu) {
last = last - num;
}
if (next == yu) {
next = next - num;
}
if (nextlast) {
index = count1;
}
}
return index;
}
3)能否杠牌
* 判断能否杠牌
*
* @param paiList 所有?牌
* @param targetPai ?标牌
* @param gangType 杠类型
* @return
*/
public static boolean canGang(ListInteger paiList, int targetPai, int gangType) {
int[][] allPai = changeToArr(paiList);
int idx = targetPai / 10;
int pos = targetPai % 10;
int yetPaiNum = allPai[idx - 1][pos];
switch (gangType) {
case 1: {// 暗杠 - 4张?样的?牌
return yetPaiNum == 4;
}
case 2: {// 明杠 -3张?张的?牌
return yetPaiNum == 3;
}
}
return false;
}
4)能否碰牌
/**
* 判断能否碰牌
*
* @param allPai 所有?牌
* @param targetPai ?标牌
* @return
*/
public static boolean canPeng(ListInteger paiList, int targetPai) {
int[][] allPai = changeToArr(paiList);
int idx = targetPai / 10;
int pos = targetPai % 10;
int yetPaiNum = allPai[idx - 1][pos];
if (yetPaiNum =2) {//?上该?标牌超过两张,可执?碰操作
return true;
}
return false;
}
5)选择打某张牌(基本)
* 根据玩家的碰杠牌选择打的牌避免花猪
* @param list ?牌
* @param map 碰杠牌堆
* @param tuoPai 癞?牌
* @return
*/
public static int chosePai(ListInteger list, MapInteger, ListInteger map , int tuoPai){ int pai = 0;//要打出去的牌
int total = 0;//花?总数
int huaSe = 0;//记录最少的花?
ListInteger indexList = new ArrayListInteger();//碰杠牌的类型集合
for(Map.EntryInteger, ListInteger entry : map.entrySet()){
int key = entry.getKey();
if (indexList != null!indexList.contains(key / 10 - 1)) {
indexList.add(key / 10 - 1);
}
}
int[][] allPai = changeToArr(list);
allPai[tuoPai/10 - 1][0] -= allPai[tuoPai/10 - 1][tuoPai % 10];
allPai[tuoPai/10 - 1][tuoPai % 10] = 0;//把癞?牌的数量置零
for(int index = 0 ; index3 ; index){//遍历三种花?牌的情况,
if (indexList.contains(index)) {
continue;
}
if (total == 0) {
total = allPai[index][0];
huaSe = index;
}
if (totalallPai[index][0]) {
total = allPai[index][0];
huaSe = index;
}
}
for(int i = 1; i10 ; i){//选择最左的牌
if (allPai[huaSe][i]0) {
pai = (huaSe1) * 10i;
break;
}
}
return pai;
}
6)对对胡
* 对对胡
* @param allPai 所有?牌
* @return
*/
public static boolean duiduiHu(int[][] allPai) {
// 对对胡
boolean isDuizi = true;
if (allPai[0][0]allPai[1][0]allPai[2][0] != 14) {//所有?牌?共14张,对对胡有7个对? return false;
}
//遍历所有?牌
for (int i = 0; i3; i) {
for (int j = 1; j = 9; j) {
if (allPai[i][j]0(allPai[i][j] != 2allPai[i][j] != 4)) {
isDuizi = false;
break;
}
}
if (!isDuizi) {
break;
}
}
if (isDuizi) {
return true;
}
return false;
}
7)?将听牌列表
/**
* ?将缺什么牌型完整
*
* @param allPai
* @return
*/
public static ListInteger quePai(int[][] allPai) {
int pai = 0;
ListInteger tingTable = new ArrayList();
for (int i = 1; i = 3; i) {
ListInteger duizi = new ArrayListInteger();
for (int j = 1; j = 9; j) {//遍历每?张牌,统计每张牌组合牌型
pai = 10 * ij;
int yu = pai / 10 - 1;
int mod = pai % 10;
// 是否有对?
int size = allPai[yu][mod];//这种牌pai张数
if (size == 0) {
continue;
}
boolean hasShun = shunFilter(allPai, pai, tingTable);
if (size == 2!hasShun) {//没有带顺序的牌并且是?对的
duizi.add(pai);
}
if (size == 2hasShun) {//有带顺序的牌并且是?对的
if (!tingTable.contains(pai)) {
tingTable.add(pai);
tingTable.add(pai);
}
}
if (size == 2) {
if (!tingTable.contains(pai)) {
tingTable.add(pai);
}
}
if (size == 3hasShun) {
duizi.add(pai);
}
}
if (duizi.size()1) {
for (Integer data : duizi) {
if (!tingTable.contains(data)) {
tingTable.add(data);
}
}
}
}
// 连续牌缺牌的整体判断
for (int i = 1; i = 3; i) {
MapInteger, Integer shun = new HashMapInteger, Integer(); int max = 0;
int start = 0;
int yu = i - 1;
for (int j = 1; j = 9; j) {
int next = 1;
start = j;
for (int k = j; k = 8; k) {
if (allPai[yu][k]0allPai[yu][k1]0) {
next;
} else {
break;
}
}
if (next3) {
shun.put(start, next);
}
if (nextmax) {
max = next;
}
}
for (Map.EntryInteger, Integer entry : shun.entrySet()) {
for (int k = 0; kentry.getValue(); k) {
pai = 10 * ientry.getKey()k;
if (!tingTable.contains(pai)) {
tingTable.add(pai);
}
}
if (entry.getKey()1) {
pai = 10 * ientry.getKey() - 1;
if (!tingTable.contains(pai)) {
tingTable.add(pai);
}
}
int end = entry.getKey()entry.getValue();
if (end10) {
pai = 10 * iend;
if (!tingTable.contains(pai)) {
tingTable.add(pai);
}
}
}
}
shun.clear();
}
return tingTable;
}
注:未完待续,?将算法较为复杂的地?是听牌列表判断、能否胡牌判断、特别是有癞?牌的时候简直是噩梦

5.9
百度文库VIP限时优惠现在开通,立享6亿 VIP内容
立即获取
麻将算法(上)
?将算法(上)
?、?将规则(云南昭通?将)
1.牌
1) “万”“筒”和“条”三房牌 , 各36张,共108张牌;
2) 只能 “碰”“杠”“胡”,不能吃牌
3) 4?进?游戏;
4) 游戏开始时,庄家摸14张牌,闲家摸13张牌;
5) 有4个癞?牌(坨牌:既可以作为本?牌型可以替换为任意牌)
第 1 页
2.游戏术语
1) 坎:???中有三张相同的牌;
2) 碰牌:???中有两张 , 别?再打出?张,则可以?两张去碰,并将这三张亮出来;
3) 明杠:???中有?坎,别?在打出?张 , 则可以?三张去杠,称之为明杠,所有的杠都是从牌墙前?补牌的 。
4) 暗杠:??摸到了四张相同的牌,则可以暗杠;
5) 补杠:??已经碰了的牌 , ???摸到了第4张,则可以补杠;
第 2 页
6) 根:??的?牌和碰牌中有四张相同的但是没杠下来的,称之为根;
7) 叫:即听牌,?户当前的13张牌,再摸?张牌就可以和牌的牌型;
8) 墙?:摸完牌后,翻出?张牌,放在下家的堆牌区中 。
9) 坨:摸完牌后 , 翻出牌墙第?张牌,定义为癞?牌 。
10) 满飞满杀:坨拿去杠 。
案例1:?上2个5条,有?打出5条 , 可以拿2个5条加1个坨去杠5条
案列2:已碰了3万,?上有坨,可以直接拿坨去杠3万
第 3 页
11) 飞碰:坨加?张单牌拿去碰的过程 。
12) 亮牌:胡牌后亮出所有牌(牌桌上的玩家都可以看),剩下的继续?战 。
3.胡牌规则
1) 胡牌条件:缺?门成牌型即可胡牌
缺?门:游戏开始后 , 必须打缺?门,中途可以换打缺哪门(不是定缺),胡牌局牌时必须只有2 门或1门(筒、万、条牌型)胡牌的基本牌型:
i. 11、123、123、123、123;
ii. 11、123、123、123、111/1111(下同);
第 4 页
iii. 11、123、123、111、111;
iv. 11、123、111、111、111;
v. 11、111、111、111、111;
vi. 11、22、33、44、55、66、77;
2) 牌型
牌型说明
棒棒正常普通的和牌,所谓的平胡
勾胡?上有杠的牌型
天胡庄家起?牌就和牌
地胡庄家打出的第??牌被闲家和
第 5 页
清??只有?种花?的牌型
杠上炮玩家杠了之后摸起来那张牌点的炮
杠上花玩家杠了以后?摸,?论暗杠、明杠、加杠都相当于?摸抢杠和别?补杠的杠牌(不是补杠后摸得那张)
?对?11、111、111、111、111的牌型
巧七对11、22、33、44、55、66、77的牌型
龙七对11、22、33、44、55、6666的牌型
?、?将算法设计(?维数组形式)
第 6 页
1.类型定义(类型*10)
万 10 (万牌的张数)
11——19 ?万-九万
筒 20 (筒牌的张数)
21——29 1筒 - 9筒
条 30 (条?牌的张数)
31——31 1条 - 9条
风牌 40(?前?风牌)41——49 东南西北中发?
2.牌下标定义
麻将游戏一般是用什么语言开发的 , 哪部分代码最难实现?多是C语言,其他的语言只有能实现 , 也可以 。
最重要也是最难实现的部分,应该是核心玩法的代码 , 需要考虑周到,仔细架构 。
如果你要做,建议找经验丰富的技术公司,像是摩天游科技,专门做地方游戏的,技术经验丰富 , 基本不会出现太大问题 。
原创干货!麻将平胡算法此算法基本可以通用于所有麻将的平胡规则,即满足m * ABCn * AAAAA(其中m、n可为0)的胡牌公式 , 红黑字牌也可由此算法演变 。
首先,我们要约定每张麻将都可以由一个数字表示,比如11表示一万,12表示二万,21表示一条,22表示二条,31表示一筒,32表示二筒……
即所有牌用两位数表示 , 表示万条筒的两位数个位为牌点,十位为牌类型,其它表示非字牌的两位数与牌类型相同,以下用一个枚举类定义:
以上定义了各张牌的数字表示,接下来我们分析手牌的存储结构,手牌可以用一个数组表示 , 数组下标号能除尽10的数组元素为保留位,不用于存储任何数据 。举例解释此数组存储牌的数据结构:
0号下标保留位
1~9号下标为万字牌牌点 , 其对应的数组元素为牌的张数
10号下标保留位
11~19号下标为条字牌牌点 , 其对应的数组元素为牌的张数
20号下标为保留位
21~29号下标为筒字牌牌点,其对应的数组元素为牌的张数
40~46号下标分别表示东、南、西、北、中、发、白的存储位 。
根据以上的定义,则可以根据数组下标获得万条筒字牌的类型和牌点,(下标/101) 则为字牌类型,(下标) 则为字牌点数 。
准备工作都做好了,怎么使用上面定义的数据结构实现平胡算法呢?平胡满足m * ABCn * AAAAA(其中m、n可为0)的胡牌公式,分析此公式,AA表示一对牌,则算法必然需要分析手牌中是否含有一对牌,ABC表示三张相同类型且连续的牌,AAA表示三张相同类型且牌点也相同的牌 。
依据公式,我们用递归思路编写一个平胡胡牌算法(其中包含简单的测试用例):
觉得不错请点赞支持,欢迎留言或进我的个人群855801563领取【架构资料专题目合集90期】、【BATJTMD大厂JAVA面试真题1000 】,本群专用于学习交流技术、分享面试机会 , 拒绝广告,我也会在群内不定期答题、探讨 。
java麻将算法代码的介绍就聊到这里吧 , 感谢你花时间阅读本站内容 , 更多关于麻将游戏编程算法、java麻将算法代码的信息别忘了在本站进行查找喔 。

    推荐阅读