マイクロソフトの新言語 Bosque

公開日:2019-04-20
最終更新:2019-04-20

マイクロソフトが新たな言語を開発らしい。。。

GitHubにサンプルコードがある。
https://github.com/Microsoft/BosqueLanguage

サンプルコード

//-------------------------------------------------------------------------------------------------------  
// Copyright (C) Microsoft. All rights reserved.  
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.  
//-------------------------------------------------------------------------------------------------------  

//  
//This is a bosque test/benchmark for a tic-tac-toe program.  
//  

namespace NSMain;  

entity Board {  
    const playerX: String[PlayerMark] = 'x'#PlayerMark;  
    const playerO: String[PlayerMark] = 'o'#PlayerMark;  

    const allCellPositions: List[[Int, Int]] = List[[Int, Int]]@{  
        @[ 0, 0 ], @[ 1, 0 ], @[ 2, 0 ],  
        @[ 0, 1 ], @[ 1, 1 ], @[ 2, 1 ],  
        @[ 0, 2 ], @[ 1, 2 ], @[ 2, 2 ]  
    };  

    const winPositionOptions: List[List[[Int, Int]]] = List[List[[Int, Int]]]@{  
        List[[Int, Int]]@{ @[ 0, 0 ], @[ 0, 1 ], @[ 0, 2 ] },  
        List[[Int, Int]]@{ @[ 0, 1 ], @[ 1, 1 ], @[ 2, 1 ] },  
        List[[Int, Int]]@{ @[ 0, 2 ], @[ 1, 2 ], @[ 2, 2 ] },  

        List[[Int, Int]]@{ @[ 0, 0 ], @[ 1, 0 ], @[ 2, 0 ] },  
        List[[Int, Int]]@{ @[ 1, 0 ], @[ 1, 1 ], @[ 1, 2 ] },  
        List[[Int, Int]]@{ @[ 2, 0 ], @[ 2, 1 ], @[ 2, 2 ] },  

        List[[Int, Int]]@{ @[ 0, 0 ], @[ 1, 1 ], @[ 2, 2 ] },  
        List[[Int, Int]]@{ @[ 0, 2 ], @[ 1, 1 ], @[ 2, 0 ] }  
    };  

    //Board is a list of marks, indexed by x,y coords from upper left 0 based  
    field cells: List[String[PlayerMark]?];  

    factory static createInitialBoard(): { cells: List[String[PlayerMark]?] } {  
        return @{ cells=List[String[PlayerMark]?]::createOfSize(9, none) };  
    }  

    method getOpenCells(): List[[Int, Int]] {  
        return Board::allCellPositions->filter(fn(pos: [Int, Int]): Bool => {  
            return !this->isCellOccupied(pos[0], pos[1]);  
        });  
    }  

    method getCellContents(x: Int, y: Int): String[PlayerMark]?   
        requires 0 <= x && x < 3 && 0 <= y && y < 3;  
    {  
        return this.cells->at(x + y * 3);  
    }  

    method isCellOccupied(x: Int, y: Int): Bool {  
        return this->getCellContents(x, y) != none;  
    }  

    method isCellOccupiedWith(x: Int, y: Int, mark: String[PlayerMark]): Bool   
        requires mark == Board::playerX || mark == Board::playerO;   
    {  
        return this->getCellContents(x, y) == mark;  
    }  

    method markCellWith(x: Int, y: Int, mark: String[PlayerMark]): Board   
        requires mark == Board::playerX || mark == Board::playerO;  
        requires 0 <= x && x < 3 && 0 <= y && y < 3;  
        requires !this->isCellOccupied(x, y);  
    {  
        return this<~(cells=this.cells->set(x + y * 3, mark));  
    }  

    hidden method checkSingleWinOption(opt: List[[Int, Int]], mark: String[PlayerMark]): Bool {  
        return opt->all(fn(entry: [Int, Int]): Bool => this->isCellOccupiedWith(entry[0], entry[1], mark));  
    }  

    hidden method checkSingleWinner(mark: String[PlayerMark]): Bool {  
        return Board::winPositionOptions->any(fn(opt: List[[Int, Int]]): Bool => this->checkSingleWinOption(opt, mark));  
    }  

    method checkForWinner(): String[PlayerMark]? {  
        if(this->checkSingleWinner(Board::playerX)) {  
            return Board::playerX;  
        }  
        elif(this->checkSingleWinner(Board::playerO)) {  
            return Board::playerO;  
        }  
        else {  
            return none;  
        }  
    }  
}  

entity Game {  
    field winner: String[PlayerMark]? = none;  
    field board: Board = [email protected]();  

    method hasWinner(): Bool {  
        return this.winner != none;  
    }  

    method getWinner(): String[PlayerMark]   
        requires this->hasWinner();  
    {  
        return this.winner->as[String[PlayerMark]]();  
    }  

    method makeAutoMove(mark: String[PlayerMark], rnd: Int): Game  
        requires !this->hasWinner();  
    {  
        var! nboard: Board;  
        if(!this.board->isCellOccupied(1, 1)) {  
            nboard = this.board->markCellWith(1, 1, mark);  
        }  
        else {  
            var opts = this.board->getOpenCells();  
            var tup = opts->uniform(rnd);  
            nboard = this.board->markCellWith(...tup, mark);  
        }  

        return this<~( board=nboard, winner=nboard->checkForWinner() );  
    }  

    method makeExplicitMove(x: Int, y: Int, mark: String[PlayerMark]): Game   
        requires !this.board->isCellOccupied(x, y);  
    {  
        var nboard = this.board->markCellWith(x, y, mark);  
        return this<~( board=nboard, winner=nboard->checkForWinner() );  
    }  
}  

entity PlayerMark provides Parsable {  
    field mark: String;  

    override static tryParse(str: String): PlayerMark | None {  
        return (str == "x" || str == "o") ? [email protected]{ mark=str } : none;  
    }  
}  

entrypoint function main(): Game {  
    var! game = [email protected]{};  

    game = game->makeAutoMove(Board::playerX, 0);  
    game = game->makeAutoMove(Board::playerO, 1);  
    game = game->makeAutoMove(Board::playerX, 2);  

    game = game->makeExplicitMove(2, 0, Board::playerO);  
    game = game->makeExplicitMove(2, 1, Board::playerX);  

    return game;  
}  

テクニカルペーパー
https://www.microsoft.com/en-us/research/uploads/prod/2019/04/beyond_structured_report_v2.pdf

記事が少しでもいいなと思ったらクラップを送ってみよう!
41
+1
@tafutadaの技術ブログ

よく一緒に読まれている記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる

技術ブログをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

技術ブログを開設する

Qrunchでアウトプットをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

Markdownで書ける

ログ機能でアウトプットを加速

デザインのカスタマイズが可能

技術ブログ開設

ここから先はアカウント(ブログ)開設が必要です

英数字4文字以上
.qrunch.io
英数字6文字以上
ログインする