随意敲的,做之前没有考虑的很多,导致有很多不合理的地方.在这里把代码记录一下,以后如果有时间再细化优化(大概率没时间).
package item.doudizhu;
import java.util.*;
/**
* 斗地主
*/
public class DoudizhuDemo1 {
public static void main(String[] args) {
//建立三个玩家对象.一个牌库
Player yang = new Player("yang");
Player li = new Player("li");
Player zhang = new Player("zhang");
ArrayList<Player> players = new ArrayList<>();
HashMap<Integer, Card> cards = new HashMap<>();
//建立斗地主牌库
create(cards);
// showC(cards);
//1.开始游戏
go(yang, li, zhang, cards, players); //洗牌 发牌 抢地主 返回底牌
// for (Player player : players) {
// System.out.println(player.getName());
// }
//2.轮流出牌 返回赢家
Player winner = play(players.listIterator(0).next(),
players.listIterator(1).next(),
players.listIterator(2).next(), cards);
if (winner.getD()) { //如果赢家是地主
System.out.println("地主胜利!恭喜" + winner.getName());
} else { //如果赢家是农民
System.out.print("农民胜利!恭喜");
for (Player player : players) {
if (!player.getD()) {
System.out.print(player.getName() + " ");
}
}
System.out.println();
}
}
/**
* 建立牌库
*
* @param cards
*/
public static void create(HashMap<Integer, Card> cards) {
String[] color = {"♠", "♥", "♣", "♦"};
String[] num = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"};
int index = 0;
for (int i = 0; i < num.length; i++) {
for (int j = 0; j < color.length; j++) {
Card card = new Card(color[j], num[i]);
cards.put(index++, card);
}
}
Card daWang = new Card(" ", "DA");
Card xiaoWang = new Card(" ", "XIAO");
cards.put(index++, xiaoWang);
cards.put(index, daWang);
}
/**
* 开局斗地主游戏并初始化 洗牌 发牌 留底牌 抢地主
*
* @param p1
* @param p2
* @param p3
* @param cards
* @param players
*/
public static void go(Player p1, Player p2, Player p3, HashMap<Integer, Card> cards, ArrayList players) {
//洗牌 发牌 留底牌
ArrayList arrayList = new ArrayList<>(cards.keySet()); //将hashmap牌库的键值存入arraylist以便进行排序
ArrayList<Integer> diPai = new ArrayList<>();
//1.洗牌 使用collections工具类的方法shuffle
Collections.shuffle((List<?>) arrayList); //洗牌
for (int i = 0; i < cards.size(); i++) { //发牌
if (i > 50) {
diPai.add((Integer) arrayList.get(i)); //将后三张牌存入底牌arraylist
continue;
}
Integer integer = (Integer) arrayList.get(i);
// System.out.println(integer);
if (i % 3 == 0) {
p1.putMyCards(integer);
} else if (i % 3 == 1) {
p2.putMyCards(integer);
} else if (i % 3 == 2) {
p3.putMyCards(integer);
}
}
System.out.println("\n性❤感❤荷❤官❤在❤线❤发❤牌\n");
// showC(p1.getMyCards(), cards);
// System.out.println("------------------");
// showC(p2.getMyCards(), cards);
// System.out.println("------------------");
// showC(p3.getMyCards(), cards);
// System.out.println("------------------");
// System.out.print("底牌:");
// showC(diPai, cards);
// System.out.println();
//抢地主
Scanner scanner = new Scanner(System.in);
ArrayList<Player> p = new ArrayList<>();
p.add(p1);
p.add(p2);
p.add(p3);
for (Player player : p) {
showC(player.getMyCards(), cards);
System.out.println(player.getName() + "是否抢地主?(y/n)");
String next1 = scanner.nextLine();
String next = next1.toLowerCase();
if (next.equals("y")) {
player.setD(true); //给该玩家置地主位
players.add(0, player);
p.remove(player);
player.getMyCards().addAll(diPai);
System.out.println(player.getName() + "是本局的地主");
System.out.print("底牌:");
showC(diPai, cards);
System.out.println();
break;
}
}
if (!p1.getD() && !p2.getD() && !p3.getD()) {
System.out.println("没人叫地主,这牌没法打了");
System.exit(0);
}
players.addAll(p);
}
/**
* 轮流出牌 游戏方法
*
* @param p1
* @param p2
* @param p3
* @param cards
*/
public static Player play(Player p1, Player p2, Player p3, HashMap<Integer, Card> cards) {
Scanner scanner = new Scanner(System.in);
ArrayList<Integer> preCards = new ArrayList<>();//用于存储上家打出的牌 下家出的牌必须比上家的大
StringBuilder preType = new StringBuilder();//用于记录上家出的牌的类型
int temp = 0; //记录出牌总次数
int cotNull = 0; //记录空过次数 若连续两次空过,则清空preCards
while (true) { //玩家轮流循环出牌
if (p1.getMyCards().size() == 0) { //判断手牌数.若为0,游戏结束,玩家胜利,结束方法.
System.out.println("游戏结束!");
return p1;
}
if (p2.getMyCards().size() == 0) {
System.out.println("游戏结束!");
return p2;
}
if (p3.getMyCards().size() == 0) {
System.out.println("游戏结束!");
return p3;
}
// System.out.println("上家牌集合是空的吗:" + preCards.isEmpty());
System.out.print("上家出的牌:");
for (Integer preCard : preCards) {
System.out.print(cards.get(preCard).getNum() + " ");
}
System.out.println();
System.out.println("上家的牌型:" + preType);
if (temp % 3 == 0) { //p1玩家出牌
showC(p1.getMyCards(), cards);
System.out.println("现在由" + p1.getName() + "出牌(输入空格代表空过):");
String next1 = scanner.nextLine(); //键入要出的牌的牌面
if (next1.equals(" ") && !preCards.isEmpty()) { //如果输入的是空 就是要不起
cotNull++; //空过判断数++
if (cotNull == 2) { //当有连续两个空过时,清空上家出的牌preCards 并将空过判断数置0
preCards.clear();
preType.delete(0, preType.length());
cotNull = 0;
}
System.out.println("要不起");
temp++;
continue;
}
String next = next1.toUpperCase().trim();
if (next.indexOf(" ") != -1) { //判断字符串里有两个连续空格的话 提示
System.out.println("不能出空格哦");
continue;
}
//创建一个返回值是boolean的验证方法 判断出的牌是否符合规则,并更新preCards和玩家的手牌:
if (!verity(next, preCards, preType, cards, p1)) {
System.out.println("会不会玩儿啊?");
continue;
}
cotNull = 0; //运行到这里说明出牌成功,空过判断数置0
} else if (temp % 3 == 1) { //p2玩家出牌
showC(p2.getMyCards(), cards);
System.out.println("现在由" + p2.getName() + "出牌(输入空格代表空过):");
String next2 = scanner.nextLine();
if (next2.equals(" ") && !preCards.isEmpty()) {
cotNull++;
if (cotNull == 2) {
preCards.clear();
preType.delete(0, preType.length());
cotNull = 0;
}
System.out.println("要不起");
temp++;
continue;
}
String next = next2.toUpperCase().trim();
if (next.indexOf(" ") != -1) {
System.out.println("不能出空格哦");
continue;
}
if (!verity(next, preCards, preType, cards, p2)) {
System.out.println("会不会玩儿啊?");
continue;
}
cotNull = 0;
} else if (temp % 3 == 2) { //p3玩家出牌
showC(p3.getMyCards(), cards);
System.out.println("现在由" + p3.getName() + "出牌(输入空格代表空过):");
String next3 = scanner.nextLine();
if (next3.equals(" ") && !preCards.isEmpty()) {
cotNull++;
if (cotNull == 2) {
preCards.clear();
preType.delete(0, preType.length());
cotNull = 0;
}
System.out.println("要不起");
temp++;
continue;
}
String next = next3.toUpperCase().trim();
if (next.indexOf(" ") != -1) {
System.out.println("不能出空格哦");
continue;
}
if (!verity(next, preCards, preType, cards, p3)) {
System.out.println("会不会玩儿啊?");
continue;
}
cotNull = 0;
}
temp++;
}
}
/**
* 验证出的牌是否合法
*
* @param next
* @param preCards
* @param preType
* @param cards
* @return
*/
private static boolean verity(String next, ArrayList<Integer> preCards,
StringBuilder preType, HashMap<Integer, Card> cards, Player player) {
//克隆一份玩家手牌
ArrayList<Integer> myClone = (ArrayList<Integer>) player.getMyCards().clone();
//1.将输入的字符串转换成权重arraylist存进preCards.
ArrayList<Integer> nowCards = new ArrayList<>();//用于存储当前玩家打出的牌 用于跟preCards比较
String type = null; //用来存储当前出牌类型
String[] split = next.split(" ");//字符串分割
for (int i = 0; i < split.length; i++) {//判断出的牌手里是否有
boolean b = false; //用于判断出的牌是否手牌里有
for (Integer integer : myClone) {
b = cards.get(integer).getNum().equals(split[i]);//从手牌中查找此牌面的权重
if (b) {
myClone.remove(integer);
nowCards.add(integer); //将权重存入出牌区
break;
}
}
if (!b) {
System.out.println("你竟然想出你没有的牌...");
return false;
}
}
//按斗地主顺序码牌并生成新的next字符串
next = shufC(nowCards, cards); //形如"2 2 2 2 K K K 6 6 XIAO 9 J DA 10"
//根据新串更新nowCards
myClone = (ArrayList<Integer>) player.getMyCards().clone();
nowCards.clear();
String[] split1 = next.split(" ");//字符串分割
Set<Map.Entry<Integer, Card>> entries = cards.entrySet();
for (String s : split1) {
for (Integer integer : myClone) {
boolean b = cards.get(integer).getNum().equals(s);//从手牌中查找此牌面的权重
if (b) {
myClone.remove(integer);
nowCards.add(integer); //将权重存入出牌区
break;
}
}
}
// System.out.println("最终的nowCards:" + nowCards.toString());
//根据有序的字符串判断牌型
type = typeJudge(next);
System.out.println("您出的牌型:" + type);
System.out.println("********************************************华丽的分割线*************************************************");
if (type.equals("ERROR")) { //验证出的牌是否符合排列规则
System.out.println("出的牌不符合规则...");
return false;
}
if (!preCards.isEmpty()) { //上家若出过牌
if ("王炸".contentEquals(preType)) {
System.out.println("王炸谁来都不好使...");
return false;
}
if (!type.equals("炸弹") && !type.equals("王炸")) {
if (!type.contentEquals(preType) || nowCards.size() != preCards.size()) { //继续验证出的牌是否与上家出的牌型一样
System.out.println("出的牌跟上家不是一种牌...");
return false;
}
}
// System.out.println(nowCards.get(0) + "//" + preCards.get(0));
//再根据牌型判断大小(通常都可以用第一个字符来比较)
if (!rankJudge(type, next, nowCards, preType, preCards, cards)) {
System.out.println("出的牌没上家大...");
return false;
}
}
player.changeMyCards(myClone); //更新玩家的手牌
preCards.clear();
preCards.addAll(nowCards);//更新上家出的牌
preType.replace(0, preType.length(), type);
List<Integer> objectMy = player.getMyCards();
List<Integer> objectNow = nowCards;
// System.out.println("手牌:" + objectMy);
// System.out.println("出的牌" + objectNow);
return true;
}
/**
* 码牌 把出现次数最多的牌面排在前面
*
* @param nowCards
* @param cards
* @return 返回码好的牌(字符串形式)
*/
private static String shufC(ArrayList<Integer> nowCards, HashMap<Integer, Card> cards) {
Collections.sort(nowCards); //给出的牌排序
StringBuilder stringBuilder = new StringBuilder();
for (Integer nowCard : nowCards) {
stringBuilder.append(cards.get(nowCard).getNum()).append(" ");//查牌库中权重对应的牌面
}
String next = "" + stringBuilder;
next = next.toUpperCase().trim(); //把从小到大排列的权重集合转换为相应的字符串
// 把next里所有的10替换成0
// next.replace("10","0");
// next.replace(" ","");
//按照字符出现次数降序排序 若出现次数相同就按照权重升序排序
HashMap<String, Integer> cotTimes = new HashMap<>(); //用于存储字符串出现的次数
String[] split = next.split(" ");
for (String s : split) { //计算出每个字符串的出现次数
if (cotTimes.containsKey(s)) {
Integer integer = cotTimes.get(s) + 1;
cotTimes.put(s, integer);
} else {
cotTimes.put(s, 1);
}
}
//通过Arraylist构造函数把map.entrySet()转化为list(map没有按值排序的方法,我们要把map转化为list)
List<Map.Entry<String, Integer>> list = new ArrayList<>(cotTimes.entrySet());
//用Comparator比较器进行排序
list.sort((o1, o2) -> {
Integer key1 = null;
Integer key2 = null;
if (o1.getValue().equals(o2.getValue())) { //若出现次数相同则按照权重升序排序
Set<Map.Entry<Integer, Card>> entries = cards.entrySet();
for (Map.Entry<Integer, Card> entry : entries) {
if (entry.getValue().getNum().equals(o1.getKey())) {
key1 = entry.getKey(); //取得第一个元素的权重
}
if (entry.getValue().getNum().equals(o2.getKey())) {
key2 = entry.getKey(); //取得第二个元素的权重
}
} // 按照权重升序排序
return key1 > key2 ? 1 : -1;
}
//按出现次数从大到小逆序排序
return o1.getValue() > o2.getValue() ? -1 : 1;
});
StringBuilder res = new StringBuilder();
//遍历排好序的列表,得到排好序的集合,然后按值遍历,将键key放到res中,输出字符串)
for (Map.Entry<String, Integer> entry : list) {
//对每一个值进行遍历,例如a出现三次,遍历3次,将a加入res,e出现2词,遍历2次,将e加入res......
for (int i = 0; i < entry.getValue(); i++) {
res.append(entry.getKey() + " ");
}
}
next = res.toString().trim();
System.out.println("您出的牌:" + next);
return next;
}
/**
* 判断出的牌是什么类型
*
* @param next
* @return 返回出牌类型 (字符串) 不合法则返回"ERROR"
*/
public static String typeJudge(String next) {
String linkCards1 = "34567890JQKA";// 顺子
String linkCards2 = "3344556677889900JJQQKKAA";// 连对
String linkCards3 = "333444555666777888999000JJJQQQKKKAAA";// 飞机
String[] split = next.split(" ");//字符串分割
next = next.replace(" ", ""); //去掉字符串里的空格
next = next.replace("10", "0"); //将10替换为0
next = next.replace("DA", "D"); //D代表大王
next = next.replace("XIAO", "X"); //X代表小王
// System.out.println(next.length());
// System.out.println(next);
if (next.contains("D") && next.contains("X") && next.length() != 2) { //王炸
return "ERROR";
}
if (split.length == 1) { //单
return "单";
} else if (split.length == 2) {
if ((split[0] + split[1]).contains("DA") && (split[0] + split[1]).contains("XIAO")) { //王炸
return "王炸";
}
if (split[0].equals(split[1])) {
return "对";
}
} else if (split.length == 3) {
if (split[0].equals(split[1]) && split[1].equals(split[2])) {
return "三带";
}
} else if (split.length == 4) {
if (split[0].equals(split[1]) && split[1].equals(split[2]) && split[2].equals(split[3])) {
return "炸弹";
}
if (next.matches("(.)\\1{2,3}.{1}")) { //三带一
return "三带一";
}
} else if (split.length == 5) {
if (next.matches("(.)\\1{2,3}(.)\\2{1}")) { //三带二
return "三带二";
}
if (linkCards1.contains(next)) { //顺子
return "顺子";
}
} else if (split.length > 5) {
if (linkCards1.contains(next)) { //顺子
return "顺子";
}
if (next.matches("(.)\\1{2}(.)\\2{2}.*")) { //飞机
if (next.length() % 3 == 0 && linkCards3.contains(next)) { //飞机无翅膀
return "飞机无翅膀";
}
if (next.length() == 8 && next.matches("(.)\\1{2}(.)\\2{2}.{2}")) { //飞机单翅膀 3311
// System.out.println("测试"+next);
if (!split[split.length - 1].equals(split[split.length - 2])) {
String substring = next.substring(0, next.length() - 3);
// System.out.println(substring);
if (linkCards3.contains(substring)) {
return "飞机单翅膀";
}
}
}
if (next.length() == 12 && next.matches("(.)\\1{2}(.)\\2{2}(.)\\3{2}.{3}")) { //飞机单翅膀 333111
if (!split[split.length - 1].equals(split[split.length - 2]) && !split[split.length - 2].equals(split[split.length - 3])) {
String substring = next.substring(0, next.length() - 4);
if (linkCards3.contains(substring)) {
return "飞机单翅膀";
}
}
}
if (next.length() == 16 && next.matches("(.)\\1{2}(.)\\2{2}(.)\\3{2}(.)\\4{2}.{4}")) { //飞机单翅膀 33331111
if (!split[split.length - 1].equals(split[split.length - 2]) &&
!split[split.length - 2].equals(split[split.length - 3]) &&
!split[split.length - 3].equals(split[split.length - 4])) {
String substring = next.substring(0, next.length() - 5);
if (linkCards3.contains(substring)) {
return "飞机单翅膀";
}
}
}
if (next.length() == 10 && next.matches("(.)\\1{2}(.)\\2{2}(.)\\3{1}(.)\\4{1}")) { //飞机对翅膀 3322
if (!split[split.length - 1].equals(split[split.length - 3])) {
String substring = next.substring(0, next.length() - 5);
if (linkCards3.contains(substring)) {
return "飞机对翅膀";
}
}
}
if (next.length() == 15 && next.matches("(.)\\1{2}(.)\\2{2}(.)\\3{2}(.)\\4{1}(.)\\5{1}(.)\\6{1}")) { //飞机对翅膀 333222
if (!split[split.length - 1].equals(split[split.length - 3]) && !split[split.length - 3].equals(split[split.length - 5])) {
String substring = next.substring(0, next.length() - 7);
if (linkCards3.contains(substring)) {
return "飞机对翅膀";
}
}
}
if (next.length() == 20 && next.matches("(.)\\1{2}(.)\\2{2}(.)\\3{2}(.)\\4{2}(.)\\5{1}(.)\\6{1}(.)\\7{1}(.)\\8{1}")) { //飞机对翅膀 33332222
if (!split[split.length - 1].equals(split[split.length - 3]) &&
!split[split.length - 3].equals(split[split.length - 5]) &&
!split[split.length - 5].equals(split[split.length - 7])) {
String substring = next.substring(0, next.length() - 9);
if (linkCards3.contains(substring)) {
return "飞机对翅膀";
}
}
}
}
if (linkCards2.contains(next)) { //连对
if((split[0].equals(split[1] ))&&
(split[split.length-1].equals(split[split.length-2])) &&
(split.length%2==0)){
return "连对";
}
}
if (next.matches("(.)\\1{3}.{2}")) { //四带二
if (!split[split.length - 1].equals(split[split.length - 2])) {
return "四带二";
}
}
if (next.matches("(.)\\1{3}(.)\\2{1}(.)\\3{1}")) { //四带四
if (!split[split.length - 1].equals(split[split.length - 3])) { //防止出现5555 6666 的牌型
return "四带四";
}
}
}
return "ERROR";
}
/**
* 按照斗地主规则判断牌大小
*
* @param type
* @param next
* @param nowCards
* @param preCards
* @param cards
* @return 符合规则返回true 不符合返回false
*/
private static boolean rankJudge(String type, String next, ArrayList<Integer> nowCards, StringBuilder preType,
ArrayList<Integer> preCards, HashMap<Integer, Card> cards) {
//之后验证是否符合大小规则 后出 > 先出
// 1.单 判断单张权重大小 再根据preCards里的权重通过牌库hash找到对应的牌面 如果牌面相同 不允许出牌
if (type.equals("单")) {
if (nowCards.get(0) < preCards.get(0) || cards.get(preCards.get(0)).getNum().equals(next)) {
return false;
} else return true;
}
// 2.对 判断nowCards中第一位的权重大小即可 如果牌面相同 不允许出牌
if (type.equals("对")) {
if (nowCards.get(0) < preCards.get(0) || cards.get(preCards.get(0)).getNum().equals(next.substring(0, 1))) {
return false;
} else return true;
}
// 3.三带 判断nowCards中第一位的权重大小即可 如果牌面相同 不允许出牌
if (type.equals("三带")) {
if (nowCards.get(0) < preCards.get(0) || cards.get(preCards.get(0)).getNum().equals(next.substring(0, 1))) {
return false;
} else return true;
}
// 4.三带一 三张相同牌中的任一牌面按照权重比较大小
if (type.equals("三带一")) {
if (nowCards.get(0) < preCards.get(0) || cards.get(preCards.get(0)).getNum().equals(next.substring(0, 1))) {
return false;
} else return true;
}
// 三带二 三张相同牌中的任一牌面按照权重比较大小
if (type.equals("三带二")) {
if (nowCards.get(0) < preCards.get(0) || cards.get(preCards.get(0)).getNum().equals(next.substring(0, 1))) {
return false;
} else return true;
}
// 5.飞机 任意一个机身的牌面权重 > 先出的任意一个机身的牌面权重
if (type.equals("飞机无翅膀") || type.equals("飞机单翅膀") || type.equals("飞机对翅膀")) {
if (nowCards.get(0) < preCards.get(0) || cards.get(preCards.get(0)).getNum().equals(next.substring(0, 1))) {
return false;
} else return true;
}
// 6.连对(最小为三对) 最小的两张相同牌牌面权重 > 先出的最小的两张相同牌牌面权重 && length相等
if (type.equals("连对")) {
if (nowCards.get(0) < preCards.get(0) || cards.get(preCards.get(0)).getNum().equals(next.substring(0, 1))) {
return false;
} else return true;
}
// 7.顺子 (最小是5张) 最小的牌面权重 > 先出的最小牌面权重 && length相等
if (type.equals("顺子")) {
if (nowCards.get(0) < preCards.get(0) || cards.get(preCards.get(0)).getNum().equals(next.substring(0, 1))) {
return false;
} else return true;
}
// 8.四带二 四张相同牌中的任一牌面按照权重比较大小
if (type.equals("四带二")) {
if (nowCards.get(0) < preCards.get(0) || cards.get(preCards.get(0)).getNum().equals(next.substring(0, 1))) {
return false;
} else return true;
}
// 9.炸弹 大于其他所有类型 && 四张相同牌中的任一牌面按照权重比较大小 && 大小王大于所有牌
if (type.equals("炸弹")) {
if (preType.equals("炸弹")) { //如果上家出的也是炸弹
if (nowCards.get(0) < preCards.get(0) || cards.get(preCards.get(0)).getNum().equals(next.substring(0, 1))) {
return false;
}
} else if (!preType.equals("王炸")) { //如果上家出的不是王炸
return true;
}
}
if (type.equals("王炸")) {
return true;
}
return false;
}
/**
* 码牌并展示手牌(仅仅展示用,带花色)
*
* @param myCards
*/
private static void showC(ArrayList<Integer> myCards, HashMap<Integer, Card> cards) {
Collections.sort(myCards);
System.out.print("[");
for (Integer myCard : myCards) {
System.out.print(cards.get(myCard).getColor() + cards.get(myCard).getNum() + " ");
}
System.out.println("]");
}
/**
* 展示牌库
*
* @param cards
*/
public static void showC(HashMap<Integer, Card> cards) {
for (Map.Entry<Integer, Card> entry : cards.entrySet()) {
System.out.println("权:" + entry.getKey() + " 牌面:" + entry.getValue().getColor() + entry.getValue().getNum());
}
}
}
/**
* 卡牌类
*/
class Card {
private String color; //♠ ♥ ♣ ♦ ' '
private String num; //3 4 5 6 7 8 9 10 J Q K A 2 小王 大王
public Card(String color, String num) {
this.color = color;
this.num = num;
}
public Card() {
}
public String getColor() {
return color;
}
public String getNum() {
return num;
}
@Override
public String toString() {
return "Card{" +
"color='" + color + '\'' +
", num='" + num + '\'' +
'}';
}
}
/**
* 玩家类
*/
class Player {
private String name; //名字
private ArrayList<Integer> myCards = new ArrayList<>(); //手牌的权重序列
private Boolean isD = false; //地主判断位
public void setD(Boolean d) {
isD = d;
}
public Player(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ArrayList<Integer> getMyCards() {
return myCards;
}
public void changeMyCards(ArrayList<Integer> myCards) {
this.myCards = myCards;
}
public void putMyCards(Integer card) {
this.myCards.add(card);
}
public boolean getD() {
return this.isD;
}
}
版权声明:本文为weixin_44855583原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。