0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Flutterでバトルシップパズルを作成する3

Last updated at Posted at 2021-09-22

概要

Flutterでバトルシップパズルを作成する
縦横サイズ、船の種類と数、波の数を引数で渡せるようにする
表示を改善(クリアメッセージを表示する、下に船の種類と数を表示する)
セルデータを自動生成ロジックの改善

実行環境

Mac

$ sw_vers
ProductName:    macOS
ProductVersion: 11.6
BuildVersion:   20G165

Flutter

$ flutter --version
Flutter 2.5.1 • channel stable • https://github.com/flutter/flutter.git
Framework • revision ffb2ecea52 (5 days ago) • 2021-09-17 15:26:33 -0400
Engine • revision b3af521a05
Tools • Dart 2.14.2

修正内容

縦横サイズ、船の種類と数、波の数を引数で渡せるようにする

class BattleshipApp extends StatelessWidget {
  final int rows, columns, waves;
  late final List<Ship> ships;

  BattleshipApp({this.columns = 10, this.rows = 10, this.waves = 2}) {
    ships = [
      const Ship(4, 1),
      const Ship(3, 2),
      const Ship(2, 3),
      const Ship(1, 4)
    ];
  }

  @override
  Widget build(BuildContext context) => MaterialApp(
        home: Scaffold(
          appBar: AppBar(
            title: const Text('BattleshipPuzzle'),
          ),
          body: _BattleshipHome(rows, columns, ships, waves),
        ),
      );
}

表示改善

共通部分

Widget _buildContainer() => Center(
      child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
        const SizedBox(height: 20),
        Row(mainAxisAlignment: MainAxisAlignment.center, children: [
          ElevatedButton(
            onPressed: () => _pushReset(),
            child: const Text('Reset'),
          ),
          const SizedBox(width: 20),
          Text('TapCount: $_tapCount'),
        ]),
        const SizedBox(height: 20),
        SizedBox(
          width: 440,
          height: 440,
          child: Stack(
            children: [
              Center(
                child: Container(
                  child: _buildClearText(),
              ),
              ),
              _buildColumn(),
            ],
          ),
        ),
        Padding(
          padding: const EdgeInsets.fromLTRB(0, 0, 0, 0),
          child: _buildBottom(),
        ),
      ]),
    );

クリアメッセージを表示する

Widget? _buildClearText() {
  if (_remainCount == 0) {
    return Text(
      "Clear!!",
      style: TextStyle(
        fontWeight: FontWeight.bold,
        fontSize: 50.0,
        color: Colors.pink[500],
      ),
    );
  } else {
    return null;
  }
}

下に船の種類と数を表示する

Widget _buildBottom() {
  final column = Column(
      children:
          List.generate(_ships.length, (index) => _buildShips(_ships[index])));
  return SizedBox(
    width: 440,
    height: 160,
    child: column,
  );
}

Widget _buildShips(Ship ship) {
  return Row(
    children: List.generate(ship.num, (index) => _buildShip(ship.size)),
  );
}

Widget _buildShip(int size) {
  if (size == 1) {
    return SizedBox(
    width: 40,
      height: 40,
      child: _buildShipCircle(),
    );
  } else {
    List<Widget> row = [];
    row.add(
      SizedBox(
        width: 40,
        height: 40,
        child: _buildShipRoundLeft(),
      ),
    );
    for (var sizeIndex = 2; sizeIndex < size; sizeIndex++) {
      row.add(
        SizedBox(
          width: 40,
          height: 40,
          child: _buildShipSquare(),
        ),
      );
    }
    row.add(
      SizedBox(
        width: 40,
        height: 40,
        child: _buildShipRoundRight(),
      ),
    );
    return SizedBox(
      width: size * 40,
      height: 40,
      child: Row(children: row),
    );
  }
}

セルデータを自動生成ロジックの改善

船が配置できるかチェック(横方向)

bool canExistsHorizontal(
    List<List<CellType>> cellTypes, Ship ship, int row, int column) {
  if (_columns < column + ship.size) {
    return false;
  }
  // 上下チェック
  for (var i = column - 1; i <= column + ship.size; i++) {
    if (i < 0 || _columns <= i) {
      continue;
    }
    if (0 < row && cellTypes[row - 1][i] != CellType.None) {
      return false;
    }
    if (cellTypes[row][i] != CellType.None) {
      return false;
    }
    if (row + 1 < _rows && cellTypes[row + 1][i] != CellType.None) {
      return false;
    }
  }
  return true;
}

船が配置できるかチェック(縦方向)

bool canExistsVertical(
    List<List<CellType>> cellTypes, Ship ship, int row, int column) {
  if (_rows < row + ship.size) {
    return false;
  }
  // 左右チェック
  for (var i = row - 1; i <= row + ship.size; i++) {
    if (i < 0 || _rows <= i) {
      continue;
    }
    if (0 < column && cellTypes[i][column - 1] != CellType.None) {
      return false;
    }
    if (cellTypes[i][column] != CellType.None) {
      return false;
    }
    if (column + 1 < _columns && cellTypes[i][column + 1] != CellType.None) {
      return false;
    }
  }
  return true;
}

アプリの実行

アプリを起動

flutter run

実行結果

battleship3.gif

GitHub

Webアプリ

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?