2025-11-07 17:07:22 +09:00
|
|
|
import 'package:flutter/material.dart';
|
2025-11-11 14:38:15 +09:00
|
|
|
import 'package:sudoku_app/models/sudoku_theme.dart';
|
2025-11-07 17:07:22 +09:00
|
|
|
|
|
|
|
|
class SudokuBoard extends StatelessWidget {
|
|
|
|
|
final int blockSize;
|
2025-11-11 14:38:15 +09:00
|
|
|
final SudokuTheme theme;
|
|
|
|
|
final List<int> cells;
|
|
|
|
|
final List<int> originalCells;
|
2025-11-07 17:07:22 +09:00
|
|
|
final int? selectedIndex;
|
2025-11-11 14:38:15 +09:00
|
|
|
final int? selectedNumberPad;
|
2025-11-07 17:07:22 +09:00
|
|
|
final Set<int> incorrectCells;
|
|
|
|
|
final Function(int) onCellTapped;
|
|
|
|
|
|
|
|
|
|
const SudokuBoard({
|
|
|
|
|
super.key,
|
|
|
|
|
required this.blockSize,
|
2025-11-10 18:02:01 +09:00
|
|
|
required this.theme,
|
2025-11-07 17:07:22 +09:00
|
|
|
required this.cells,
|
|
|
|
|
required this.originalCells,
|
|
|
|
|
required this.selectedIndex,
|
|
|
|
|
required this.selectedNumberPad,
|
|
|
|
|
required this.incorrectCells,
|
|
|
|
|
required this.onCellTapped,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
|
final int gridSize = blockSize * blockSize;
|
|
|
|
|
final double fontSize = (gridSize > 9) ? (gridSize > 16 ? 12 : 16) : 24;
|
|
|
|
|
|
|
|
|
|
return AspectRatio(
|
|
|
|
|
aspectRatio: 1.0,
|
|
|
|
|
child: GridView.builder(
|
|
|
|
|
physics: const NeverScrollableScrollPhysics(),
|
|
|
|
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
|
|
|
|
crossAxisCount: gridSize,
|
|
|
|
|
),
|
|
|
|
|
itemCount: gridSize * gridSize,
|
|
|
|
|
itemBuilder: (context, index) {
|
|
|
|
|
int row = index ~/ gridSize;
|
|
|
|
|
int col = index % gridSize;
|
|
|
|
|
|
2025-11-11 14:38:15 +09:00
|
|
|
int cellValue = cells[index];
|
2025-11-10 18:02:01 +09:00
|
|
|
bool isEditable = (originalCells[index] == 0);
|
2025-11-07 17:07:22 +09:00
|
|
|
bool isSelected = (index == selectedIndex);
|
|
|
|
|
|
2025-11-11 14:38:15 +09:00
|
|
|
int selectedNumAsInt = selectedNumberPad ?? -1;
|
|
|
|
|
String selectedNumAsSymbol = (selectedNumberPad != null) ? theme.getSymbol(selectedNumberPad!) : "";
|
|
|
|
|
|
2025-11-10 18:02:01 +09:00
|
|
|
bool isHighlighted = (cellValue != 0 &&
|
2025-11-07 17:07:22 +09:00
|
|
|
selectedNumberPad != null &&
|
2025-11-10 18:02:01 +09:00
|
|
|
cellValue == selectedNumberPad);
|
2025-11-07 17:07:22 +09:00
|
|
|
|
|
|
|
|
bool isIncorrect = incorrectCells.contains(index);
|
|
|
|
|
|
|
|
|
|
BorderSide thickBorder = const BorderSide(color: Colors.black, width: 2.0);
|
|
|
|
|
BorderSide thinBorder = const BorderSide(color: Colors.grey, width: 0.5);
|
|
|
|
|
|
|
|
|
|
return GestureDetector(
|
|
|
|
|
onTap: () => onCellTapped(index),
|
|
|
|
|
child: Container(
|
|
|
|
|
alignment: Alignment.center,
|
|
|
|
|
decoration: BoxDecoration(
|
2025-11-11 14:38:15 +09:00
|
|
|
// 🔽 [수정] 'isSelected' 조건 제거 (배경색 없음)
|
2025-11-07 17:07:22 +09:00
|
|
|
color: isIncorrect
|
2025-11-11 14:38:15 +09:00
|
|
|
? Colors.red.shade100 // 1순위: 틀림
|
|
|
|
|
: isHighlighted
|
|
|
|
|
? Colors.blue.shade200 // 2순위: 숫자 하이라이트
|
|
|
|
|
: isEditable
|
|
|
|
|
? Colors.white
|
|
|
|
|
: Colors.grey.shade200, // 기본
|
2025-11-07 17:07:22 +09:00
|
|
|
border: Border(
|
|
|
|
|
top: (row == 0) ? thickBorder : thinBorder,
|
|
|
|
|
left: (col == 0) ? thickBorder : thinBorder,
|
|
|
|
|
right: (col == gridSize - 1) ? thickBorder : (col % blockSize == blockSize - 1) ? thickBorder : thinBorder,
|
|
|
|
|
bottom: (row == gridSize - 1) ? thickBorder : (row % blockSize == blockSize - 1) ? thickBorder : thinBorder,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
child: Text(
|
|
|
|
|
cellValue == 0 ? '' : theme.getSymbol(cellValue),
|
|
|
|
|
style: TextStyle(
|
|
|
|
|
fontSize: fontSize,
|
|
|
|
|
fontWeight: FontWeight.bold,
|
2025-11-11 14:38:15 +09:00
|
|
|
// 🔽 [수정] 'isSelected'를 최우선 순위로 추가 (텍스트 색상 변경)
|
|
|
|
|
color: isSelected
|
|
|
|
|
? Colors.orange.shade700 // 1순위: 선택된 셀
|
|
|
|
|
: isIncorrect
|
|
|
|
|
? Colors.red.shade900 // 2순위: 틀린 셀
|
|
|
|
|
: isEditable
|
|
|
|
|
? Colors.blue // 3순위: 수정 가능 셀
|
|
|
|
|
: Colors.black, // 기본 (원본 숫자)
|
2025-11-07 17:07:22 +09:00
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|