edit_fen.dart 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. import 'package:cchess/cchess.dart';
  2. import 'package:flutter/material.dart';
  3. import 'chess_box.dart';
  4. import 'chess_pieces.dart';
  5. import 'chess_single_box.dart';
  6. import 'board.dart';
  7. import '../global.dart';
  8. import '../pages/home_page.dart';
  9. import '../models/game_manager.dart';
  10. /// 编辑局面
  11. class EditFen extends StatefulWidget {
  12. final String fen;
  13. const EditFen({Key? key, required this.fen}) : super(key: key);
  14. @override
  15. State<EditFen> createState() => EditFenState();
  16. }
  17. class EditFenState extends State<EditFen> {
  18. late ChessManual manual;
  19. GameManager? gamer;
  20. late List<ChessItem> items;
  21. ChessItem? activeItem;
  22. String activeChr = '';
  23. String dieChrs = '';
  24. @override
  25. void initState() {
  26. super.initState();
  27. manual = ChessManual();
  28. manual.setFen(widget.fen);
  29. items = manual.getChessItems();
  30. dieChrs = manual.currentFen.getDieChr();
  31. }
  32. @override
  33. void dispose() {
  34. super.dispose();
  35. }
  36. void editOK() {
  37. Navigator.of(context).pop<String>(manual.currentFen.fen);
  38. }
  39. bool onPointer(ChessPos toPosition) {
  40. ChessItem targetItem = items.firstWhere(
  41. (item) => !item.isBlank && item.position == toPosition,
  42. orElse: () => ChessItem('0'),
  43. );
  44. if (targetItem.isBlank) {
  45. if (activeItem != null) {
  46. manual.doMove('${activeItem!.position.toCode()}${toPosition.toCode()}');
  47. setState(() {
  48. activeItem!.position = toPosition;
  49. activeItem = null;
  50. });
  51. return true;
  52. } else if (activeChr.isNotEmpty) {
  53. manual.setItem(toPosition, activeChr);
  54. setState(() {
  55. items = manual.getChessItems();
  56. activeChr = '';
  57. dieChrs = manual.currentFen.getDieChr();
  58. });
  59. return true;
  60. }
  61. } else {
  62. if (activeItem != null) {
  63. if (activeItem!.position == toPosition) {
  64. manual.setItem(toPosition, '0');
  65. setState(() {
  66. items = manual.getChessItems();
  67. activeItem = null;
  68. dieChrs = manual.currentFen.getDieChr();
  69. });
  70. } else {
  71. //targetItem.position = ChessPos.fromCode('i4');
  72. //targetItem.isDie = true;
  73. manual
  74. .doMove('${activeItem!.position.toCode()}${toPosition.toCode()}');
  75. setState(() {
  76. items = manual.getChessItems();
  77. activeItem = null;
  78. });
  79. }
  80. return true;
  81. } else if (activeChr.isNotEmpty && activeChr != targetItem.code) {
  82. //targetItem.position = ChessPos.fromCode('i4');
  83. bool seted = manual.setItem(toPosition, activeChr);
  84. if (seted) {
  85. setState(() {
  86. items = manual.getChessItems();
  87. activeChr = '';
  88. dieChrs = manual.currentFen.getDieChr();
  89. });
  90. }
  91. } else {
  92. setState(() {
  93. activeItem = targetItem;
  94. activeChr = '';
  95. });
  96. }
  97. }
  98. return false;
  99. }
  100. void removeItem(ChessPos fromPosition) {
  101. manual.currentFen[fromPosition.y][fromPosition.x] = '0';
  102. setState(() {
  103. items = manual.getChessItems();
  104. activeItem = null;
  105. activeChr = '';
  106. });
  107. }
  108. void setActiveChr(String chr) {
  109. setState(() {
  110. activeItem = null;
  111. activeChr = chr;
  112. });
  113. }
  114. void clearAll() {
  115. manual.setFen('4k4/9/9/9/9/9/9/9/9/4K4');
  116. setState(() {
  117. items = manual.getChessItems();
  118. dieChrs = manual.currentFen.getDieChr();
  119. activeChr = '';
  120. activeItem = null;
  121. });
  122. }
  123. ChessPos pointTrans(Offset tapPoint) {
  124. int x = (tapPoint.dx - gamer!.skin.offset.dx * gamer!.scale) ~/
  125. (gamer!.skin.size * gamer!.scale);
  126. int y = 9 -
  127. (tapPoint.dy - gamer!.skin.offset.dy * gamer!.scale) ~/
  128. (gamer!.skin.size * gamer!.scale);
  129. return ChessPos(x, y);
  130. }
  131. @override
  132. Widget build(BuildContext context) {
  133. if (gamer == null) {
  134. HomePageState gameWrapper =
  135. context.findAncestorStateOfType<HomePageState>()!;
  136. gamer = gameWrapper.gamer;
  137. }
  138. return Scaffold(
  139. appBar: AppBar(
  140. title: Text(context.l10n.editCode),
  141. actions: [
  142. TextButton(
  143. onPressed: () {
  144. editOK();
  145. },
  146. child: Text(
  147. context.l10n.save,
  148. style: const TextStyle(color: Colors.white),
  149. ),
  150. )
  151. ],
  152. ),
  153. body: Center(
  154. child: gamer!.scale < 1 ? _mobileContainer() : _windowContainer(),
  155. ),
  156. );
  157. }
  158. Widget _mobileContainer() {
  159. return SizedBox(
  160. width: gamer!.skin.width * gamer!.scale,
  161. height: (gamer!.skin.height + gamer!.skin.size * 2 + 20) * gamer!.scale,
  162. child: Row(
  163. crossAxisAlignment: CrossAxisAlignment.center,
  164. mainAxisAlignment: MainAxisAlignment.spaceAround,
  165. children: [
  166. ChessSingleBox(
  167. width: gamer!.skin.width * gamer!.scale,
  168. itemChrs: dieChrs,
  169. activeChr: activeChr,
  170. ),
  171. const SizedBox(width: 10),
  172. GestureDetector(
  173. onTapUp: (detail) {
  174. onPointer(pointTrans(detail.localPosition));
  175. },
  176. onLongPressEnd: (detail) {
  177. logger.info('longPressEnd $detail');
  178. },
  179. onPanEnd: (detail) {},
  180. child: SizedBox(
  181. width: gamer!.skin.width * gamer!.scale,
  182. height: gamer!.skin.height * gamer!.scale,
  183. child: Stack(
  184. alignment: Alignment.center,
  185. children: [
  186. const Board(),
  187. ChessPieces(
  188. items: items,
  189. activeItem: activeItem,
  190. )
  191. ],
  192. ),
  193. ),
  194. ),
  195. const SizedBox(width: 10),
  196. ChessSingleBox(
  197. width: gamer!.skin.width * gamer!.scale,
  198. itemChrs: dieChrs,
  199. activeChr: activeChr,
  200. )
  201. ],
  202. ),
  203. );
  204. }
  205. Widget _windowContainer() {
  206. return SizedBox(
  207. width: gamer!.skin.width + 10 + gamer!.skin.size * 2 + 10,
  208. child: Row(
  209. crossAxisAlignment: CrossAxisAlignment.center,
  210. children: [
  211. GestureDetector(
  212. onTapUp: (detail) {
  213. onPointer(pointTrans(detail.localPosition));
  214. },
  215. onLongPressEnd: (detail) {
  216. logger.info('longPressEnd $detail');
  217. },
  218. onPanEnd: (detail) {},
  219. child: SizedBox(
  220. width: gamer!.skin.width,
  221. height: gamer!.skin.height,
  222. child: Stack(
  223. alignment: Alignment.center,
  224. children: [
  225. const Board(),
  226. ChessPieces(
  227. items: items,
  228. activeItem: activeItem,
  229. )
  230. ],
  231. ),
  232. ),
  233. ),
  234. const SizedBox(width: 10),
  235. ChessBox(
  236. height: gamer!.skin.height,
  237. itemChrs: dieChrs,
  238. activeChr: activeChr,
  239. )
  240. ],
  241. ),
  242. );
  243. }
  244. }