You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASCII T恤艺术代码优化及前4行梯形可视化实现咨询

ASCII T恤图案代码优化与梯形可视化实现

问题背景

我用C语言实现了一个ASCII格式的T恤图案生成函数,目前是逐行判断绘制,但代码冗余度很高。想优化代码结构让它更简洁,同时想把图案的前4行拆分为两个独立的梯形(左右肩部/袖子区域),请教具体实现方法。原代码如下:

原实现代码

void 
displayShirt(char size, char neckline, char leftsleeve, char leftChest, char rightSleeve, char rightChest, char bottomLeft, char bottomRight) {

    int isRound;
    int halfColumn;
    int r;
    int c;
    int rows, columns;

    switch (size) {
        case 'S':
            rows = 10;
            columns = 18;
            break;
        case 'M':
            rows = 12;
            columns = 22;
            break;
        case 'L':
            rows = 14;
            columns = 26;
            break;
        case 'X':
            rows = 16;
            columns = 30;
            break;
    }

    halfColumn = columns / 2;

    switch (neckline) {
        case 'R':
            isRound = 1;
            break;
        case 'V':
            isRound = 0;
            break;
    }

    printf("\n\nMock Shirt:\n");


    for (r = 1; r <= rows; r++) {
        for (c = 0; c <= columns; c++) {
            if (r == 1) {
                if (c >= 0 && c <= 3)
                    printf(" ");
                else if ( (c == 4 || (c <= halfColumn - 2 || c >= halfColumn + 3)) 
                        && (c <= columns - 3))
                    printf("x");
                else printf(" ");
            }
            else if (r == 2) {
                if ((isRound == 1) && (c == halfColumn || c == halfColumn + 1 ))
                    printf("x");
                else if (c == 3 || c == halfColumn - 1 || c == halfColumn + 2 || c == columns - 2)
                    printf("x");
                else
                    printf(" ");
            }
            else if (r == 3) {
                if (c == 2)
                    printf("x");
                else if (c == 4 && (rightSleeve == 'L' || rightSleeve == 'P'))
                    printf("%c", rightSleeve);
                else if ((isRound == 0) && (c == halfColumn || c == halfColumn + 1))
                    printf("x");
                else if (c == columns - 3 && (leftsleeve == 'L' || leftsleeve == 'P'))
                    printf("%c", leftsleeve);
                else if (c == columns - 1)
                    printf("x");
                else
                    printf(" ");
            }
            else if (r == 4) {
                if (c >= 1 && c <= 4)
                    printf("x");
                else if (c == 6 && (rightChest == 'L' || rightChest == 'P' || rightChest == 'O'))
                    printf("%c", rightChest);
                else if (c == columns - 5 && (leftChest == 'L' || leftChest == 'P' || leftChest == 'O'))
                    printf("%c", leftChest);
                else if (c >= columns - 3 && c <= columns)
                    printf("x");
                else
                    printf(" ");
            }
            else if ((r >= 5 || r > rows) && ((c == 4 || c == columns - 3) || (r == rows && (c >= 4 && c <= columns - 3))))
                printf("x");
            else if (r == rows - 1 && c == 6 && bottomRight == 'O')
                printf("%c", bottomRight);
            else if (r == rows - 1 && c == columns - 5 && bottomLeft == 'O')
                printf("%c", bottomLeft);
            else
                printf(" ");
        }
        printf("\n");
    }
}

int main() {
    char size = 'M';
    char neckline = 'V';
    char leftSleeve = 'L';
    char leftChest = 'O';
    char rightSleeve = 'O';
    char rightChest = 'O';
    char bottomLeft = 'O';
    char bottomRight = 'O';

    displayShirt(size, neckline, leftSleeve, leftChest, rightSleeve, rightChest, bottomLeft, bottomRight);
    
    size = 'X';
    neckline = 'R';
    leftSleeve = 'P';
    leftChest = 'L';
    rightSleeve = 'L';
    rightChest = 'O';
    bottomLeft = 'O';
    bottomRight = 'O';
    
    displayShirt(size, neckline, leftSleeve, leftChest, rightSleeve, rightChest, bottomLeft, bottomRight);

    return 0;
}

优化思路与梯形实现方案

核心优化方向

  • 用数据结构替代冗余switch:把尺寸对应的行列数存入结构体数组,避免重复分支判断,新增尺寸只需修改数组。
  • 抽象左右梯形结构:前4行的左右两侧是对称梯形,每行的列范围有固定规律,用函数封装梯形的判断逻辑,替代逐列的if嵌套。
  • 分离基础形状与装饰元素:把领口、袖子/胸口的装饰字符和T恤基础轮廓绘制逻辑分开,让代码职责更清晰。

梯形具体实现逻辑

前4行的左右梯形列范围规律如下:

行号右侧梯形列范围左侧梯形列范围
14~4columns-3~columns-3
23~3columns-2~columns-2
32~2columns-1~columns-1
41~4columns-3~columns

通过两个辅助函数isRightTrapezoid和isLeftTrapezoid判断当前行列是否属于对应梯形,再结合装饰字符的位置逻辑完成绘制。

重构后的优化代码

#include <stdio.h>
#include <stdbool.h>

// 尺寸参数结构体,替代原switch分支
typedef struct {
    char size;
    int rows;
    int columns;
} ShirtSize;

ShirtSize sizeMap[] = {
    {'S', 10, 18},
    {'M', 12, 22},
    {'L', 14, 26},
    {'X', 16, 30}
};
int sizeCount = sizeof(sizeMap)/sizeof(sizeMap[0]);

// 获取指定尺寸对应的行列参数
void getSizeParams(char size, int *rows, int *columns) {
    for(int i=0; i<sizeCount; i++){
        if(sizeMap[i].size == size){
            *rows = sizeMap[i].rows;
            *columns = sizeMap[i].columns;
            return;
        }
    }
    // 默认返回M号参数
    *rows = 12;
    *columns = 22;
}

// 判断当前位置是否属于右侧梯形区域
bool isRightTrapezoid(int r, int c, int columns) {
    switch(r){
        case 1: return c == 4;
        case 2: return c == 3;
        case 3: return c == 2;
        case 4: return c >=1 && c <=4;
        default: return false;
    }
}

// 判断当前位置是否属于左侧梯形区域
bool isLeftTrapezoid(int r, int c, int columns) {
    switch(r){
        case 1: return c == columns -3;
        case 2: return c == columns -2;
        case 3: return c == columns -1;
        case 4: return c >= columns -3 && c <= columns;
        default: return false;
    }
}

void displayShirt(char size, char neckline, char leftSleeve, char leftChest, char rightSleeve, char rightChest, char bottomLeft, char bottomRight) {
    int rows, columns;
    getSizeParams(size, &rows, &columns);
    int halfColumn = columns / 2;
    bool isRound = (neckline == 'R');

    printf("\n\nMock Shirt:\n");

    for (int r = 1; r <= rows; r++) {
        for (int c = 0; c <= columns; c++) {
            char drawChar = ' ';

            // 绘制左右梯形及对应装饰
            if(isRightTrapezoid(r, c, columns)){
                if(r ==3 && c ==4 && (rightSleeve == 'L' || rightSleeve == 'P')){
                    drawChar = rightSleeve;
                } else if(r ==4 && c ==6 && (rightChest == 'L' || rightChest == 'P' || rightChest == 'O')){
                    drawChar = rightChest;
                } else {
                    drawChar = 'x';
                }
            } else if(isLeftTrapezoid(r, c, columns)){
                if(r ==3 && c == columns -3 && (leftSleeve == 'L' || leftSleeve == 'P')){
                    drawChar = leftSleeve;
                } else if(r ==4 && c == columns -5 && (leftChest == 'L' || leftChest == 'P' || leftChest == 'O')){
                    drawChar = leftChest;
                } else {
                    drawChar = 'x';
                }
            } 
            // 绘制领口区域
            else if(r <=3){
                if(r ==2 && isRound && (c == halfColumn || c == halfColumn +1)){
                    drawChar = 'x';
                } else if(r ==3 && !isRound && (c == halfColumn || c == halfColumn +1)){
                    drawChar = 'x';
                } else if(r ==2 && (c == halfColumn -1 || c == halfColumn +2)){
                    drawChar = 'x';
                }
            }
            // 绘制衣身主体及底部装饰
            else if(r >=5){
                if(c ==4 || c == columns -3){
                    drawChar = 'x';
                } else if(r == rows && c >=4 && c <= columns -3){
                    drawChar = 'x';
                } else if(r == rows -1){
                    if(c ==6 && bottomRight == 'O') drawChar = bottomRight;
                    else if(c == columns -5 && bottomLeft == 'O') drawChar = bottomLeft;
                }
            }

            printf("%c", drawChar);
        }
        printf("\n");
    }
}

int main() {
    char size = 'M';
    char neckline = 'V';
    char leftSleeve = 'L';
    char leftChest = 'O';
    char rightSleeve = 'O';
    char rightChest = 'O';
    char bottomLeft = 'O';
    char bottomRight = 'O';

    displayShirt(size, neckline, leftSleeve, leftChest, rightSleeve, rightChest, bottomLeft, bottomRight);
    
    size = 'X';
    neckline = 'R';
    leftSleeve = 'P';
    leftChest = 'L';
    rightSleeve = 'L';
    rightChest = 'O';
    bottomLeft = 'O';
    bottomRight = 'O';
    
    displayShirt(size, neckline, leftSleeve, leftChest, rightSleeve, rightChest, bottomLeft, bottomRight);

    return 0;
}

优化点说明

  1. 用结构体数组存储尺寸参数,新增尺寸时无需修改绘制逻辑,扩展性更强。
  2. 抽象梯形判断函数,把前4行的重复逻辑提取出来,大幅减少嵌套if的数量。
  3. 变量命名更直观(如用bool类型替代int的isRound),代码可读性提升。
  4. 分离装饰字符与基础轮廓的绘制逻辑,每个模块职责单一,便于后续维护。

内容的提问来源于stack exchange,提问作者Rommel Legaspi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 12:27:06