本课作品
制作 9 列、7 行的像素房子
一行代码让施工队动起来,一组坐标让每个方块找到自己的位置。你将完成严格9列、7行的房子,并解释门窗为什么不会被墙盖住。 前置:变量、条件、for 与 while。建议先完成第9、10课。
开始前:建议先完成第 9–10 课
01 / 12
两位建筑师,先约好顺序

村长要一座宽9格、高7格的房子。阿行负责换楼层,小列负责在当前楼层从左走到右。如果两人各走各的,房子只会变成一团石砖毛线。
程序里的约定很清楚:外层循环选中一行,内层循环走完这一行的所有列,然后换行。屏幕的行号向下增加,列号向右增加;这与“往上盖楼”的故事方向不同,要以坐标图为准。
- row 决定当前行,col 决定当前列。
- 每走完一行,内层循环会重新从 col = 0 开始。
- 每个格子打印一个字符;println 只负责结束整行。
02 / 12
两层循环怎样配合
- 外层 row选当前行
- 内层 col从0扫到最后一列
- 换行本行完成,再选下一行
L11Example02.java · 完整独立示例
public class L11Example02 {
public static void main(String[] args) {
for (int row = 0; row < 2; row++) {
for (int col = 0; col < 3; col++) {
System.out.print(row + "," + col + " ");
}
System.out.println();
}
}
}运行结果
0,0 0,1 0,2
1,0 1,1 1,2 03 / 12
给每个格子一张地址牌
| row / col | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
|---|---|---|---|---|---|---|---|
| 0 | . | . | . | . | . | . | . |
| 1 | . | . | D | . | . | . | . |
| 2 | . | . | . | . | . | . | . |
| 3 | . | . | . | . | . | . | X |
行列都从0开始。4行的合法行号是0到3,7列的合法列号是0到6。图中 D 的地址是 (1,2),X 是右下角 (3,6)。
L11Example03.java · 完整独立示例
public class L11Example03 {
public static void main(String[] args) {
for (int row = 0; row < 4; row++) {
for (int col = 0; col < 7; col++) {
System.out.print(row == 1 && col == 2 ? "D" : ".");
}
System.out.println();
}
}
}运行结果
.......
..D....
.......
.......04 / 12
四条边界,一圈围墙
| row / col | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
|---|---|---|---|---|---|---|---|
| 0 | # | # | # | # | # | # | # |
| 1 | # | # | |||||
| 2 | # | # | |||||
| 3 | # | # | # | # | # | # | # |
L11Example04.java · 完整独立示例
public class L11Example04 {
public static void main(String[] args) {
int rows = 4, cols = 7;
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
boolean edge = row == 0 || row == rows - 1
|| col == 0 || col == cols - 1;
System.out.print(edge ? "#" : " ");
}
System.out.println();
}
}
}运行结果
#######
# #
# #
#######05 / 12
让门窗先占位
| 按顺序检查 | 命中后执行 |
|---|---|
| 门条件满足 | 打印 D |
| 否则,窗条件满足 | 打印 O |
| 否则,边框满足 | 打印 # |
| 否则 | 打印空格 |
从上往下检查;只执行首个匹配的分支。
门可能就在底边,窗可能覆盖墙。若先检查墙,墙会抢走这些格子。使用 if / else if / else,让一格只选择一种符号;把更具体的门窗条件放在墙条件前面。
06 / 12
符号也需要一张材料表
- #墙体
- O窗户
- D门
- ^屋顶
- 空格室内或背景
像素画靠字符宽度维持队形。选等宽字体和半角符号;中文、表情与部分 Unicode 符号的显示宽度可能不同。每格只用一个 ASCII 字符,便于精确验收。
L11Example06.java · 完整独立示例
public class L11Example06 {
public static void main(String[] args) {
for (int row = 0; row < 4; row++) {
for (int col = 0; col < 6; col++) {
System.out.print((row + col) % 2 == 0 ? "#" : ".");
}
System.out.println();
}
}
}运行结果
#.#.#.
.#.#.#
#.#.#.
.#.#.#07 / 12
建筑故障诊所

BadRow.java · 故意错误示例
public class BadRow {
public static void main(String[] args) {
for (int row = 0; row < 2; row++) { }
System.out.println(row);
}
}- 图案变成一长列:检查 println 是否被放进内层循环。
- 少了最后一列:检查 col < cols 的边界,不能提前停在 cols - 1。
- 永远画不出右边墙:合法最后列是 cols - 1,不是 cols。
08 / 12
先预测,再允许电脑发言
| row / col | 0 | 1 | 2 | 3 |
|---|---|---|---|---|
| 0 | * | |||
| 1 | * | * | ||
| 2 | * | * | * | |
| 3 | * | * | * | * |
L11Example08.java · 完整独立示例
public class L11Example08 {
public static void main(String[] args) {
for (int row = 0; row < 4; row++) {
for (int col = 0; col <= row; col++) {
System.out.print("*");
}
System.out.println();
}
}
}运行结果
*
**
***
****09 / 12
挑战蓝图:严格9列7行
| row / col | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|---|---|---|---|---|---|---|---|---|---|
| 0 | ^ | ^ | ^ | ^ | ^ | ||||
| 1 | ^ | ^ | ^ | ^ | ^ | ^ | ^ | ||
| 2 | # | # | # | # | # | # | # | # | # |
| 3 | # | O | D | O | # | ||||
| 4 | # | O | D | O | # | ||||
| 5 | # | D | # | ||||||
| 6 | # | # | # | # | # | # | # | # | # |
先画图,再写条件。两行屋顶分别占第0行的2到6列、第1行的1到7列;门位于第4列、第3到5行;窗位于第1或7列、第3或4行。第2行是上墙,第6行是地基,两侧墙在第0和8列。
- 房子每行必须包含9个字符,前后空格也算。
- 判断顺序:屋顶、门、窗、墙、空格。
- 背景空格仍占一个格子,不能直接跳过打印。
10 / 12
完整实现:一格一个决定

PixelHouse.java · 完整独立示例
public class PixelHouse {
public static void main(String[] args) {
int rows = 7, cols = 9;
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
char block;
boolean roof = row == 0 && col >= 2 && col <= 6
|| row == 1 && col >= 1 && col <= 7;
boolean door = col == 4 && row >= 3 && row <= 5;
boolean window = (col == 1 || col == 7)
&& (row == 3 || row == 4);
boolean wall = row >= 2 && (row == 2 || row == 6
|| col == 0 || col == cols - 1);
if (roof) block = '^';
else if (door) block = 'D';
else if (window) block = 'O';
else if (wall) block = '#';
else block = ' ';
System.out.print(block);
}
System.out.println();
}
}
}运行结果
^^^^^
^^^^^^^
#########
#O D O#
#O D O#
# D #
#########11 / 12
用边界测试替房子验收
- 7行外层执行7轮
- 9列内层执行9次
- 门窗可见具体条件先于墙
验收时数行、数列,再检查关键地址:(0,2)是屋顶,(3,4)是门,(3,1)是窗,(6,8)是墙。只说“看起来像房子”还不够。
- 把 col < cols 改成 col <= cols:每行多一格,找到原因后恢复。
- 把 println 移进内层:解释为什么每个方块独占一行,再恢复。
- 增加火把:在墙条件前检查 row == 2 && col == 4,该行应变为 ####T####。
- 把通用边框例的 rows 改为1:应只输出一行;这里不要直接改固定房子的坐标。
12 / 12
轮到你设计建筑

- 木镐:画6×6空心边框,测试1行、2行及正常尺寸。
- 铁镐:画8×8棋盘,再改成9列;解释奇偶条件。
- 钻石镐:设计9×9苦力怕脸,先交坐标草图,再写眼睛与嘴的条件。
交付源代码、运行图案、行列统计和一条 Bug 记录。能解释一个坐标为什么命中某种符号,比背下整段代码更有用。
TAKE IT WITH YOU
下载本课 PDF
完整课文、代码、图解与练习,选择你需要的语言。
