Java编写五子棋训练任务

Java编写五子棋

题目

:五子棋是全国智力运动会竞技项目之一,是一种两人对弈的纯策略型棋类游戏。通常双方分别使用黑白两色的棋子,下在棋盘直线与横线的交叉点上,先形成五子连珠者获胜。
棋盘效果如下:
在这里插入图片描述

任务过程

1.绘制棋盘
2.提示黑方(用1表示)和白方(用2表示)分别表示下棋(x、y轴位置)并重新绘制棋盘
3.每当一方下棋后判断是否获胜。

厘清思路

第一步

是让我们绘制棋盘,那我们可以想到用二维数组来存储这棋盘,因为这些棋盘都是由0组成,除了第一列的每行和第一行的每一列,它们不是0,它们是为了让玩家在下棋落子时能很快找准位置,所以它们的值是和自己的列下标或行下标一一对应。OK,当我们知晓给二维数组赋这些值的时候,我们就可以遍历输入我们的二维数组,那我们的棋盘就绘制成功了。
在这里我将插入我的代码,以便大家更清醒的认识到我的思路:

在这里插入代码片
```int[][] nums = new int[16][16];   //需要存储棋盘的二维数组
  
  //遍历赋初始值全部为0
  for(int i=0; i<nums.length; i++) {
   for(int j=0; j<nums[i].length; j++) {
    nums[i][j] = 0;
   }
  }
  
  //但是第一列的每行是非0  第一行的每列也是非0
  for(int i=0; i<nums[0].length; i++) {
   nums[0][i] = i;
  }
  for(int i=0; i<nums.length; i++) {
   nums[i][0] = i;
  }
  //遍历输出 绘制棋盘
  for(int i=0; i<nums.length; i++) {
   for(int j=0; j<nums[i].length; j++) {
    System.out.print(nums[i][j]+"\t");
   }
   System.out.println();
  }

第二步

可以拆分三步,
第一步是提示玩家输入落子位置,这个很简单,但是我们在这一步我们还要考虑一个问题,是提示哪一个玩家,是黑方还是白方,还有就是下棋落子必须是轮着下,不能一直是一个选手下。所以我在这定义了一个布尔类型的变量,因为它只有两个值:true或false;当这个变量值为true时,用来提示黑方玩家下棋,那么当黑方下完后,我们把变量值变成false,那么下一次就轮到提示白方玩家下棋,然后再变值,这样就实现了黑方和白方轮着下棋。

那么第二步就是记录落子位置,并在这个位置上赋值1表示黑棋子,赋值2表示白棋子。这时我直接定义了两个和棋盘一样的二维数组,分别表示记录黑棋和白棋的数组。之所以一样,是因为为了方便赋值,因为玩家输入的是落子位置,也就是二维数组的下标,即行坐标和列坐标。我们只要对应这个用户输入的下标值来赋值1或2。当然在用户输入的过程中,我们还需要进行判断,是否为整型数,是否在棋盘的范围内,是否和对方的棋子或自己的棋子有重叠,需要很仔细的去判断有哪些细节需要考虑。当我们完成了这些判断,就可以在我们创建的记录棋子的数组上,对应玩家输入的下标位置,来赋上代表棋子的值(黑棋1或白棋2)。然后我们再把这个数组刚刚赋的值给到我们的棋盘数组上。

第三步就是玩家落子完后并重新绘制棋盘,因为玩家得看到彼此下的位置,否则怎么玩呢?鬼知道下一步往哪走。OK,其实在前面两小步都完成后,这一步就很简单了。它其实就是遍历二维数组进行输入罢了。

为了让大家更清醒的认识到我上面的思路,我将插入关于这三步的代码。

在这里插入代码片
  int[][] black = new int[16][16];  //用来记录黑棋落子位置后的棋盘
     int[][] white = new int[16][16];  //用来记录白棋落子位置后的棋盘
     
     //遍历全赋值为0 和nums数组一样,为了方便赋值对应下标位置
     for(int i =0; i<black.length;i++) {
      for(int j =0; j<black[i].length; j++) {
       white[i][j] = 0;
       black[i][j] = 0;
      }
     }
     
   //第一列的每行是非0  第一行的每列也是非0
     for(int i=0; i<black[0].length; i++) {
      black[0][i] = i;
     }
     for(int i=0; i<black.length; i++) {
      black[i][0] = i;
     }
     
    //第一列的每行是非0  第一行的每列也是非0
     for(int i=0; i<white[0].length; i++) {
      white[0][i] = i;
     }
     for(int i=0; i<white.length; i++) {
      white[i][0] = i;
     }
     
     //定义存储用户输入的坐标位置变量
     Scanner input = new Scanner(System.in);
     int c = 1;//黑棋落子行坐标位置 
     int d = 1;//黑棋落子列坐标位置
     int a = 1;//白棋落子行坐标位置
     int b = 1;//白棋落子列坐标位置
     boolean pan = true; //判断谁落子  true 表示黑棋选手落子,false表示白棋选手落子
     
 haha:  while(true) {
      if(pan) {
          System.out.println("请黑棋选手输入落子行位置  列位置 (1-15):");
          if(input.hasNextInt()) {
           c = input.nextInt();   //行位置下标
           d = input.nextInt();   //列位置下标
           
           if(c < 1|| c>15) {  
            System.out.println("没有这个行位置,你已违法规则...");
            return;
           }
           
           if(d < 1|| d>15) {
            System.out.println("没有这个列位置,你已违法规则...");
            return;
           }
           
           black[c][d] = 1;   //有这个位置对应black数组下标上并在其赋值为1 表示黑棋子
         
          }else {
           System.out.println("输入有误,强制退出游戏...");
           return;
          }
       
      }else {
        System.out.println("请白棋选手输入落子行位置  列位置 (1-15):");
           if(input.hasNextInt()) {
            a = input.nextInt();  //行位置下标
            b = input.nextInt();  //列位置下标
            
            if(a < 1|| a>15) {
             System.out.println("没有这个行位置,你已违法规则...");
             return;
            }
            
            if(b < 1|| b>15) {
             System.out.println("没有这列个位置,你已违法规则...");
             return;
            }
            
            white[a][b] = 2;   //有这个位置对应white数组下标上并在其赋值为2 表示白棋子
           
           }else {
            System.out.println("输入有误,强制退出游戏...");
            return;
           }
      
      }
     
      //落好子后赋给nums数组,因为它是我们的棋盘。
         if(pan) {   
          if(nums[c][d]!=2&&nums[c][d]!=1) {     //不能重叠自己的棋子和对方的棋子
           nums[c][d]=black[c][d];            //把落子的位置开始赋值在棋盘上
          }else {
           System.out.println("你的落子位置和其他棋子位置有重叠,已违法游戏规则,将强制退出...");
     return;
          }
          //遍历 重新绘制黑棋落子之后的棋盘,方便展示给白棋选手进行下一步落子
          System.out.println("--------------------------------------------------------------"); 
          for(int i=0; i<nums.length; i++) {
        for(int j=0; j<nums[i].length; j++) {
         System.out.print(nums[i][j]+"\t");
        }
        System.out.println();
       }
          
          pan = false;  //黑棋选手落完子之后,接着就轮到白棋选手,所以赋值为false
         
         }else {     
          if(nums[a][b]!=1&&nums[a][b]!=2){     //不能重叠自己的棋子和对方的棋子
           nums[a][b]=white[a][b];           //落子的位置开始赋值在棋盘上
          }else {
           System.out.println("你的落子位置和其他棋子位置有重叠,已违法游戏规则,将强制退出...");
     return;
          }
             //遍历重新绘制白棋落子之后的棋盘
          System.out.println("--------------------------------------------------------------");
          for(int i=0; i<nums.length; i++) {
        for(int j=0; j<nums[i].length; j++) {
         System.out.print(nums[i][j]+"\t");
        }
        System.out.println();
       }
          
          pan = true;   //白棋选手落完子之后,接着就轮到黑棋选手,所以赋值为true
         
         }

第三步
这一步就是判断胜负,赢了就终止游戏。那么怎么来判断输赢呢?我们首先得知道五子棋胜利的条件是什么?我相信大家都知道,那就是五子连珠,对吧。这个五子连珠横着连、竖着连、左斜线连、右斜线连都可以。所以我们就可以把分解成四个条件。
横线连:同一行5个挨在一起的列的值(1或2)相连
竖线连:同一列5个踩在一起的行的值(1或2)相连
左斜线连:根据行–、列++的顺序5个左斜在一起的值(1或2)相连
右斜线连:根据行++、列++的顺序5个右斜在一起的值(1或2)相连。
当我们知道这四个条件后,我们就可以遍历一一循环数组,去判断这四个条件是否有满足的。
接下来我将提供这一步的代码,方便大家更好的去理解。

在这里插入代码片
```// —— 输赢判断
                for(int x=1;x<nums.length-4;x++) {
                 for(int y=1;y<nums[x].length-4;y++) {
             
                 if(nums[x][y]==1&&nums[x][y]==nums[x][y+1]&&nums[x][y+1]==nums[x][y+2]
                &&nums[x][y+2]==nums[x][y+3]&&nums[x][y+3]==nums[x][y+4]) {
            System.out.println("胜负已分,黑棋选手胜利");
            break haha;
           }
          
              if(nums[x][y]==2&&nums[x][y]==nums[x][y+1]&&nums[x][y+1]==nums[x][y+2]
                &&nums[x][y+2]==nums[x][y+3]&&nums[x][y+3]==nums[x][y+4]) {
            System.out.println("胜负已分,白棋选手胜利");
            break haha;
           }
          
           
          // | 输赢判断
          
              if(nums[x][y]==1&&nums[x][y]==nums[x+1][y]&&nums[x+1][y]==nums[x+2][y]
                &&nums[x+2][y]==nums[x+3][y]&&nums[x+3][y]==nums[x+4][y]) {
            System.out.println("胜负已分,黑棋选手胜利");
            break haha;
           }
          
          
         
              if(nums[x][y]==2&&nums[x][y]==nums[x+1][y]&&nums[x+1][y]==nums[x+2][y]
                &&nums[x+2][y]==nums[x+3][y]&&nums[x+3][y]==nums[x+4][y]) {
            System.out.println("胜负已分,白棋选手胜利");
            break haha;
           }
          
          // \ 输赢判断
          
              if(nums[x][y]==1&&nums[x][y]==nums[x+1][y+1]&&nums[x+1][y+1]==nums[x+2][y+2]
                &&nums[x+2][y+2]==nums[x+3][y+3]&&nums[x+3][y+3]==nums[x+4][y+4]) {
            System.out.println("胜负已分,黑棋选手胜利");
            break haha;
           }
         
              if(nums[x][y]==2&&nums[x][y]==nums[x+1][y+1]&&nums[x+1][y+1]==nums[x+2][y+2]
                &&nums[x+2][y+2]==nums[x+3][y+3]&&nums[x+3][y+3]==nums[x+4][y+4]) {
            System.out.println("胜负已分,白棋选手胜利");
            break haha;
           }
         
           
          // /输赢判断
         
              if(nums[x][y]==1&&nums[x][y]==nums[(x+4)-1][y+1]&&nums[(x+4)-1][y+1]==nums[(x+4)-2][y+2]
                &&nums[(x+4)-2][y+2]==nums[(x+4)-3][y+3]&&nums[(x+4)-3][y+3]==nums[(x+4)-4][y+4]) {
            System.out.println("胜负已分,黑棋选手胜利");
            break haha;
           }
         
           
              if(nums[x][y]==21&&nums[x][y]==nums[(x+4)-1][y+1]&&nums[(x+4)-1][y+1]==nums[(x+4)-2][y+2]
                &&nums[(x+4)-2][y+2]==nums[(x+4)-3][y+3]&&nums[(x+4)-3][y+3]==nums[(x+4)-4][y+4]) {
            System.out.println("胜负已分,白棋选手胜利");
            break haha;
           }
         }

运作结果

在这里插入图片描述

完整的代码

思路清晰了,相关的代码也给你们提示了,我们自己尝试着做一下,然后我将我完整的代码提供出来,以供大家参考。

在这里插入代码片
public class WuZiQi {
public static void main(String[] args) {
  int[][] nums = new int[16][16];   //需要存储棋盘的二维数组
  
  //遍历赋初始值全部为0
  for(int i=0; i<nums.length; i++) {
   for(int j=0; j<nums[i].length; j++) {
    nums[i][j] = 0;
   }
  }
  //但是第一列的每行是非0  第一行的每列也是非0
  for(int i=0; i<nums[0].length; i++) {
   nums[0][i] = i;
  }
  for(int i=0; i<nums.length; i++) {
   nums[i][0] = i;
  }
  
  //遍历输出 绘制棋盘
  for(int i=0; i<nums.length; i++) {
   for(int j=0; j<nums[i].length; j++) {
    System.out.print(nums[i][j]+"\t");
   }
   System.out.println();
  }
  
  
     int[][] black = new int[16][16];  //用来记录黑棋落子位置后的棋盘
     int[][] white = new int[16][16];  //用来记录白棋落子位置后的棋盘
     
     //遍历全赋值为0 和nums数组一样,为了方便赋值对应下标位置
     for(int i =0; i<black.length;i++) {
      for(int j =0; j<black[i].length; j++) {
       white[i][j] = 0;
       black[i][j] = 0;
      }
     }
     
   //第一列的每行是非0  第一行的每列也是非0
     for(int i=0; i<black[0].length; i++) {
      black[0][i] = i;
     }
     for(int i=0; i<black.length; i++) {
      black[i][0] = i;
     }
     
    //第一列的每行是非0  第一行的每列也是非0
     for(int i=0; i<white[0].length; i++) {
      white[0][i] = i;
     }
     for(int i=0; i<white.length; i++) {
      white[i][0] = i;
     }
     
     //定义输入落子位置值 以及需要存储位置值的变量
     Scanner input = new Scanner(System.in);
     int c = 1;//黑棋落子行坐标位置 
     int d = 1;//黑棋落子列坐标位置
     int a = 1;//白棋落子行坐标位置
     int b = 1;//白棋落子列坐标位置
     boolean pan = true; //判断谁落子  true 表示黑棋选手落子,false表示白棋选手落子
     
 haha:  while(true) {
      if(pan) {
          System.out.println("请黑棋选手输入落子行位置  列位置 (1-15):");
          if(input.hasNextInt()) {
           c = input.nextInt();   //行位置下标
           d = input.nextInt();   //列位置下标
           
           if(c < 1|| c>15) {  
            System.out.println("没有这个行位置,你已违法规则...");
            return;
           }
           
           if(d < 1|| d>15) {
            System.out.println("没有这个列位置,你已违法规则...");
            return;
           }
           
           black[c][d] = 1;   //有这个位置对应black数组下标上并在其赋值为1 表示黑棋子
         
          }else {
           System.out.println("输入有误,强制退出游戏...");
           return;
          }
       
      }else {
        System.out.println("请白棋选手输入落子行位置  列位置 (1-15):");
           if(input.hasNextInt()) {
            a = input.nextInt();  //行位置下标
            b = input.nextInt();  //列位置下标
            
            if(a < 1|| a>15) {
             System.out.println("没有这个行位置,你已违法规则...");
             return;
            }
            
            if(b < 1|| b>15) {
             System.out.println("没有这列个位置,你已违法规则...");
             return;
            }
            
            white[a][b] = 2;   //有这个位置对应white数组下标上并在其赋值为2 表示白棋子
           
           }else {
            System.out.println("输入有误,强制退出游戏...");
            return;
           }
      
      }
     
      //落好子后赋给nums数组,因为它是我们的棋盘。
         if(pan) {   
          if(nums[c][d]!=2&&nums[c][d]!=1) {     //不能重叠自己的棋子和对方的棋子
           nums[c][d]=black[c][d];            //把落子的位置开始赋值在棋盘上
          }else {
           System.out.println("你的落子位置和其他棋子位置有重叠,已违法游戏规则,将强制退出...");
     return;
          }
          //遍历 重新绘制黑棋落子之后的棋盘,方便展示给白棋选手进行下一步落子
          System.out.println("--------------------------------------------------------------"); 
          for(int i=0; i<nums.length; i++) {
        for(int j=0; j<nums[i].length; j++) {
         System.out.print(nums[i][j]+"\t");
        }
        System.out.println();
       }
          
          pan = false;  //黑棋选手落完子之后,接着就轮到白棋选手,所以赋值为false
         
         }else {     
          if(nums[a][b]!=1&&nums[a][b]!=2){     //不能重叠自己的棋子和对方的棋子
           nums[a][b]=white[a][b];           //落子的位置开始赋值在棋盘上
          }else {
           System.out.println("你的落子位置和其他棋子位置有重叠,已违法游戏规则,将强制退出...");
     return;
          }
             //遍历重新绘制白棋落子之后的棋盘
          System.out.println("--------------------------------------------------------------");
          for(int i=0; i<nums.length; i++) {
        for(int j=0; j<nums[i].length; j++) {
         System.out.print(nums[i][j]+"\t");
        }
        System.out.println();
       }
          
          pan = true;   //白棋选手落完子之后,接着就轮到黑棋选手,所以赋值为true
         
         }
     
                 
           //判断是否输赢 ——:a[i][j]循环4次==a[i][j++] |:a[i][j]4次==a[i++][j]
           // \:a[i][j]4次==a[i++][j++]  /:a[i][j]4次==a[i--][j++]
    
          // —— 输赢判断
                for(int x=1;x<nums.length-4;x++) {
                 for(int y=1;y<nums[x].length-4;y++) {
             
                 if(nums[x][y]==1&&nums[x][y]==nums[x][y+1]&&nums[x][y+1]==nums[x][y+2]
                &&nums[x][y+2]==nums[x][y+3]&&nums[x][y+3]==nums[x][y+4]) {
            System.out.println("胜负已分,黑棋选手胜利");
            break haha;
           }
          
              if(nums[x][y]==2&&nums[x][y]==nums[x][y+1]&&nums[x][y+1]==nums[x][y+2]
                &&nums[x][y+2]==nums[x][y+3]&&nums[x][y+3]==nums[x][y+4]) {
            System.out.println("胜负已分,白棋选手胜利");
            break haha;
           }
          
           
          // | 输赢判断
          
              if(nums[x][y]==1&&nums[x][y]==nums[x+1][y]&&nums[x+1][y]==nums[x+2][y]
                &&nums[x+2][y]==nums[x+3][y]&&nums[x+3][y]==nums[x+4][y]) {
            System.out.println("胜负已分,黑棋选手胜利");
            break haha;
           }
          
          
         
              if(nums[x][y]==2&&nums[x][y]==nums[x+1][y]&&nums[x+1][y]==nums[x+2][y]
                &&nums[x+2][y]==nums[x+3][y]&&nums[x+3][y]==nums[x+4][y]) {
            System.out.println("胜负已分,白棋选手胜利");
            break haha;
           }
          
          // \ 输赢判断
          
              if(nums[x][y]==1&&nums[x][y]==nums[x+1][y+1]&&nums[x+1][y+1]==nums[x+2][y+2]
                &&nums[x+2][y+2]==nums[x+3][y+3]&&nums[x+3][y+3]==nums[x+4][y+4]) {
            System.out.println("胜负已分,黑棋选手胜利");
            break haha;
           }
         
              if(nums[x][y]==2&&nums[x][y]==nums[x+1][y+1]&&nums[x+1][y+1]==nums[x+2][y+2]
                &&nums[x+2][y+2]==nums[x+3][y+3]&&nums[x+3][y+3]==nums[x+4][y+4]) {
            System.out.println("胜负已分,白棋选手胜利");
            break haha;
           }
         
           
          // /输赢判断
         
              if(nums[x][y]==1&&nums[x][y]==nums[(x+4)-1][y+1]&&nums[(x+4)-1][y+1]==nums[(x+4)-2][y+2]
                &&nums[(x+4)-2][y+2]==nums[(x+4)-3][y+3]&&nums[(x+4)-3][y+3]==nums[(x+4)-4][y+4]) {
            System.out.println("胜负已分,黑棋选手胜利");
            break haha;
           }
         
           
              if(nums[x][y]==21&&nums[x][y]==nums[(x+4)-1][y+1]&&nums[(x+4)-1][y+1]==nums[(x+4)-2][y+2]
                &&nums[(x+4)-2][y+2]==nums[(x+4)-3][y+3]&&nums[(x+4)-3][y+3]==nums[(x+4)-4][y+4]) {
            System.out.println("胜负已分,白棋选手胜利");
            break haha;
           }
         
          
             }
             
         }
         
     }
    
 }
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,以下是一个简单的Java五子棋游戏实现示例: 首先,我们需要创建一个棋盘类来表示游戏状态。这个类应该包含一个二维数组来表示每个位置的棋子状态,一个方法来判断游戏是否结束,以及一些方法来放置棋子和计算得分等。 ```java public class ChessBoard { private int[][] board; private int size; private int winLength; public ChessBoard(int size, int winLength) { this.board = new int[size][size]; this.size = size; this.winLength = winLength; } public boolean placeChess(int x, int y, int color) { if (x < 0 || x >= size || y < 0 || y >= size || board[x][y] != 0) { return false; } board[x][y] = color; return true; } public boolean isGameOver() { return checkHorizontal() || checkVertical() || checkDiagonal(); } private boolean checkHorizontal() { for (int i = 0; i < size; i++) { for (int j = 0; j <= size - winLength; j++) { int count = 0; for (int k = 0; k < winLength; k++) { if (board[i][j+k] == board[i][j]) { count++; } } if (count == winLength) { return true; } } } return false; } private boolean checkVertical() { for (int i = 0; i <= size - winLength; i++) { for (int j = 0; j < size; j++) { int count = 0; for (int k = 0; k < winLength; k++) { if (board[i+k][j] == board[i][j]) { count++; } } if (count == winLength) { return true; } } } return false; } private boolean checkDiagonal() { for (int i = 0; i <= size - winLength; i++) { for (int j = 0; j <= size - winLength; j++) { int count1 = 0; int count2 = 0; for (int k = 0; k < winLength; k++) { if (board[i+k][j+k] == board[i][j]) { count1++; } if (board[i+k][j+winLength-1-k] == board[i][j]) { count2++; } } if (count1 == winLength || count2 == winLength) { return true; } } } return false; } public int getScore(int color) { int score = 0; for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { if (board[i][j] == color) { score++; } } } return score; } } ``` 接下来,我们需要创建一个玩家类来放置棋子。这个类可以通过控制台或图形用户界面实现。 ```java public class Player { private int color; public Player(int color) { this.color = color; } public int getColor() { return color; } public void makeMove(ChessBoard board) { Scanner scanner = new Scanner(System.in); System.out.print("Player " + color + " make a move (x y): "); int x = scanner.nextInt(); int y = scanner.nextInt(); if (!board.placeChess(x, y, color)) { System.out.println("Invalid move, please try again."); makeMove(board); } } } ``` 最后,我们需要创建一个游戏控制类来协调棋盘和玩家之间的交互。 ```java public class Game { private ChessBoard board; private Player[] players; private int currentPlayerIndex; public Game(int size, int winLength, Player[] players) { this.board = new ChessBoard(size, winLength); this.players = players; this.currentPlayerIndex = 0; } public void start() { while (!board.isGameOver()) { Player currentPlayer = players[currentPlayerIndex]; board.print(); currentPlayer.makeMove(board); currentPlayerIndex = (currentPlayerIndex + 1) % players.length; } board.print(); int winner = getWinner(); if (winner == 0) { System.out.println("Game ended in a draw."); } else { System.out.println("Player " + winner + " wins!"); } } private int getWinner() { int score1 = board.getScore(players[0].getColor()); int score2 = board.getScore(players[1].getColor()); if (score1 > score2) { return players[0].getColor(); } else if (score2 > score1) { return players[1].getColor(); } else { return 0; } } } ``` 现在我们可以创建两个玩家并启动游戏了: ```java public static void main(String[] args) { Player player1 = new Player(1); Player player2 = new Player(2); Game game = new Game(15, 5, new Player[] { player1, player2 }); game.start(); } ``` 这是一个非常基本的五子棋游戏实现示例,您可以根据自己的需要和技术水平进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值