zoukankan      html  css  js  c++  java
  • 用Dart写的黑白棋游戏

    2013年11月,Dart语言1.0稳定版SDK发布,普天同庆。从此,网页编程不再纠结了。

    在我看来,Dart语法简直就是C#的升级版,太像了。之所以喜欢Ruby的一个重要理由是支持mixin功能,而Dart也引入了mixin特性。

    最棒的是Google提供了集成开发环境——Dart Editor和Dartium,有非常强大的编辑和调试功能,既能编写网页程序,也能编写服务器端程序。

    把网站上的主要文档看完一遍后,再把SDK下载解压,就能用Dart编程了。

    第一个程序写什么呢?做了一个黑白棋游戏。

    直接上代码:

    <!DOCTYPE html>
    
    <html>
      <head>
        <meta charset="utf-8">
        <title>Reversi</title>
        <link rel="stylesheet" href="reversi.css">
      </head>
      <body>
        <h1>黑白棋</h1>
        
        <p id="score"><span class="black piece"></span>&nbsp;<span id="blackScore">2</span>
          <span class="spacer"></span><span class="white piece"></span>&nbsp;<span id="whiteScore">2</span></p>
          
        <table id="board">
        </table>
        
        <p id="message"></p>
    
        <script type="application/dart" src="reversi_ui.dart"></script>
        <script src="packages/browser/dart.js"></script>
      </body>
    </html>

    棋盘界面的生成和用户事件处理:

    import 'dart:html';
    import 'reversi_game.dart';
    
    var chess = new ChessBoard();
    var cells = new Map<DivElement,BoardCell>();
    var blackScore = querySelector("#blackScore");
    var whiteScore = querySelector("#whiteScore");
    var message = querySelector("#message");
    
    void main() {
      TableElement board = querySelector("#board");
      for(int i=0;i<ChessBoard.BoardSize;i++){
        var row = board.addRow();
        for(int j=0;j<ChessBoard.BoardSize;j++){
           var cell = row.addCell();
           var piece = new DivElement();
           cell.children.add(piece);
           piece.onClick.listen(placePiece);
           cells[piece] = chess.cells[i][j];
        }
      }
      updateCells();
    }
    
    void updateCells(){
      cells.forEach((piece, boardCell){
        piece.classes.clear();
        if(!boardCell.isEmpty){
          piece.classes.add(boardCell.piece);
        }
      });
      blackScore.text = chess.blackScore.toString();
      whiteScore.text = chess.whiteScore.toString();
      message.text = chess.message;
    }
    
    void placePiece(MouseEvent event) {
      var piece = event.target;
      var boardCell = cells[piece];
      if(chess.placePiece(boardCell)){
        updateCells();
        piece.classes.add('last');
      }else if(boardCell.isEmpty){
        message.text = chess.message;
        piece.classes.add('last');
      }
    }

    游戏的逻辑部分:

    class BoardCell {
      int row;
      int col;
      var piece;
    
      BoardCell(this.row, this.col);
    
      bool get isEmpty{
        return piece == null;
      }
    }
    
    class CellPos {
      int row;
      int col;
      CellPos(this.row, this.col);
    }
    
    class ChessBoard {
      static const BoardSize = 8;
      static const white = 'white';
      static const black = 'black';
    
      var currentTurn = black;
      List<List<BoardCell>> cells;
      int blackScore = 2;
      int whiteScore = 2;
    
      bool gameOver = false;
      String tip;
    
      ChessBoard(){
        cells = new List<List<BoardCell>>();
        for(int i=0;i<BoardSize;i++){
          var row = new List<BoardCell>();
          for(int j=0;j<BoardSize;j++){
            var cell = new BoardCell(i, j);
            row.add(cell);
          }
          cells.add(row);
        }
    
        cells[3][3].piece = white;
        cells[3][4].piece = black;
        cells[4][3].piece = black;
        cells[4][4].piece = white;
    
        tip = "游戏开始";
      }
    
      switchTurn(){
        currentTurn = getReverse(currentTurn);
      }
    
      String getReverse(String piece){
        if(piece == black){
          return white;
        }else if(piece == white){
          return black;
        }else{
          return null;
        }
      }
    
      bool placePiece(BoardCell cell){
        if(cell.isEmpty){
          var success = reverseOpponents(cell, currentTurn);
          if(success){
            cell.piece = currentTurn;
            calculateScore();
            switchTurn();
            if(canPlacePiece(currentTurn)){
              tip = null;
            }else{
              switchTurn();
              if(canPlacePiece(currentTurn)){
                tip = "${players[getReverse(currentTurn)]}无棋";
              }else{
                gameOver = true;
              }
            }
            return true;
          }else{
            tip = "落子无效";
          }
        }
        return false;
      }
    
      static List<CellPos> w(int row, int col){
        List<CellPos> adjacentCells = [];
        for(int j = col - 1; j >= 0; j--){
          adjacentCells.add(new CellPos(row, j));
        }
        return adjacentCells;
      }
    
      static List<CellPos> e(int row, int col){
        List<CellPos> adjacentCells = [];
        for(int j = col + 1; j < BoardSize; j++){
          adjacentCells.add(new CellPos(row, j));
        }
        return adjacentCells;
      }
    
      static List<CellPos> n(int row, int col){
        List<CellPos> adjacentCells = [];
        for(int i = row - 1; i >= 0; i--){
          adjacentCells.add(new CellPos(i, col));
        }
        return adjacentCells;
      }
    
      static List<CellPos> s(int row, int col){
        List<CellPos> adjacentCells = [];
        for(int i = row + 1; i < BoardSize; i++){
          adjacentCells.add(new CellPos(i, col));
        }
        return adjacentCells;
      }
    
      static List<CellPos> ne(int row, int col){
        List<CellPos> adjacentCells = [];
        for(int i = row - 1, j = col + 1; i >= 0 && j < BoardSize; i--, j++){
          adjacentCells.add(new CellPos(i, j));
        }
        return adjacentCells;
      }
    
      static List<CellPos> se(int row, int col){
        List<CellPos> adjacentCells = [];
        for(int i = row + 1, j = col + 1; i < BoardSize && j < BoardSize; i++, j++){
          adjacentCells.add(new CellPos(i, j));
        }
        return adjacentCells;
      }
    
      static List<CellPos> sw(int row, int col){
        List<CellPos> adjacentCells = [];
        for(int i = row + 1, j = col - 1; i < BoardSize && j >= 0; i++, j--){
          adjacentCells.add(new CellPos(i, j));
        }
        return adjacentCells;
      }
    
      static List<CellPos> nw(int row, int col){
        List<CellPos> adjacentCells = [];
        for(int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--){
          adjacentCells.add(new CellPos(i, j));
        }
        return adjacentCells;
      }
    
      var directions = [n, ne, e, se, s, sw, w, nw];
    
      List<BoardCell> findReverible(BoardCell cell, String piece){
        List<BoardCell> allOpponents = [];
        for(var direction in directions){
          List<BoardCell> opponents = [];
          for(var cellPos in direction(cell.row, cell.col)){
            var nextCell = cells[cellPos.row][cellPos.col];
            if(nextCell.piece == getReverse(piece)){
              opponents.add(nextCell);
            }else{
              if(nextCell.piece == piece){
                allOpponents.addAll(opponents);
              }
              break;
            }
          }
        }
        return allOpponents;
      }
    
      bool reverseOpponents(BoardCell cell, String piece){
        List<BoardCell> allOpponents = findReverible(cell, piece);
        if(allOpponents.length > 0){
          allOpponents.forEach((opp){opp.piece=piece;});
          return true;
        }else{
          return false;
        }
      }
    
      bool canPlacePiece(String piece){
        for(int i=0;i<BoardSize;i++){
          for(int j=0;j<BoardSize;j++){
            var cell = cells[i][j];
            if(cell.isEmpty &&
                findReverible(cell, piece).length > 0){
              return true;
            }
          }
        }
        return false;
      }
    
      calculateScore(){
        whiteScore = 0;
        blackScore = 0;
        for(int i=0;i<BoardSize;i++){
          for(int j=0;j<BoardSize;j++){
            var piece = cells[i][j].piece;
            if(piece == white){
              whiteScore++;
            }else if(piece == black){
              blackScore++;
            }
          }
        }
      }
    
      var players = {black:"黑方", white:"白方"};
    
      String get message {
        if(gameOver){
          if(whiteScore > blackScore){
            return "白方胜!";
          }else if(whiteScore < blackScore){
            return "黑方胜!";
          }else{
            return "双方平局!";
          }
        }
        if(tip == null){
          return "${players[currentTurn]}走棋";
        }else{
          return "$tip,${players[currentTurn]}走棋";
        }
      }
    }
    View Code

    开发完成后,用dart2js转成javascript,然后拷贝到网站服务器上,就可以在线玩了。

    点此打开

    以上只是一个简单的界面和走棋逻辑,接下来要做的是加入人工智能,可以人机对战;使用WebSocket通信,实现联网对战。

    这部分的代码就不贴上来了。
    点此打开试玩

    联网对弈功能需要运行游戏服务器程序,目前只能在局域网使用。

    想要完整源代码的朋友可以发邮件给我:251024877@qq.com。不要在评论中留下email,这种的我不会回的。

  • 相关阅读:
    Socket通信
    浏览器调用打印机
    python dict操作
    python list操作
    python 模块Example链接
    python random模块
    python configparser模块
    python unittest模块
    python timeit模块
    python datetime模块
  • 原文地址:https://www.cnblogs.com/rufi/p/dart-reversi.html
Copyright © 2011-2022 走看看