引き続き将棋盤を作っていきます。
使用技術
- Vue.js3
- Vite
- SCSS
今回は、駒を並べる機能を作成します。
型定義
ほぼ初めてTypeScriptを使ってみます。
駒の種類を型として定義します。
union型を使っていますが、ググるとenumよりをこちらを使えと出てきたからです。理由は追い追い理解していきます。
export type PieceType = 'king' // 王将・玉将 | 'rook' // 飛車 | 'bishop' // 角行 | 'gold' // 金将 | 'silver' // 銀将 | 'knight' // 桂馬 | 'lance' // 香車 | 'pawn'; // 歩兵
クラス定義
駒一枚一枚の状態などを表現するクラスを作成します。
export class Piece { id: number; type: PieceType; // 駒の種類 isFirst: boolean; // true: 先手, false: 後手 isPromoted: boolean; // true: 成り column: number; // 列 row: number; // 行 constructor(type: PieceType, isFirst: boolean, column: number, row: number) { this.type = type; this.isFirst = isFirst; this.isPromoted = false; this.column = column; this.row = row; this.id = autoIncrementId; autoIncrementId += 1; } ... }
このPiece
のインスタンスの配列を用意すれば、画面機能が良い感じに表示してくれる、という想定です。
画面表示
Pieceクラスの情報を元に、position: absolute
で駒を画面配置します。
methods: { pieceStyle(piece) { return { right: (21 + 51 * (piece.column - 1)) + 'px', top: (21 + 51 * (piece.row - 1)) + 'px', transform: 'rotate(' + (piece.isFirst ? 0 : 180) + 'deg)', } }, },
画面に並べます。
<div v-for="p in pieces" class="piece" :style="pieceStyle(p)" :key="p.id" > {{ p.name }} </div>
Pieceインスタンス作成
いい感じの関数を作りました。
トリッキーなので良し悪しは半々です。
/** * @param name 駒の名前 * @param positions 先手の駒配置の配列 [[column, row], [column, row], ...] * @return 先手後手両方分のPieceのconstructorの引数 */ const splitFirstAndSecond = (name, positions) => positions .flatMap((position) => ([ // 先手 [true, position[0], position[1]], // 後手 [false, 10 - position[0], 10 - position[1]], ])) .map((position) => [name, ...position])
methods: { initPieces() { this.pieces = [ ...splitFirstAndSecond('king', [[5, 9]]), ...splitFirstAndSecond('rook', [[2, 8]]), ...splitFirstAndSecond('bishop', [[8, 8]]), ...splitFirstAndSecond('gold', [[4, 9], [6, 9]]), ...splitFirstAndSecond('silver', [[3, 9], [7, 9]]), ...splitFirstAndSecond('knight', [[2, 9], [8, 9]]), ...splitFirstAndSecond('lance', [[1, 9], [9, 9]]), ...splitFirstAndSecond('pawn', [[1, 7], [2, 7], [3, 7], [4, 7], [5, 7], [6, 7], [7, 7], [8, 7], [9, 7]]), ] .map((params) => new Piece(...params)) }
完成した画面
ソースコード
https://github.com/nek0meshi/shogi-board/pull/2
まとめ
ベースとなるクラス定義と画面表示ができました。
TypeScriptを使えたのは嬉しいです。少しずつ理解していきたいです。
次回以降は駒を動かしていきます。