#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// 宏定义,用于设定游戏中的常量
#define MAX_HEALTH 100
#define MIN_ATTACK 10
#define MAX_ATTACK 20
// --- 角色结构体定义 ---
// `Character` 结构体用于代表一个战斗角色,包含其姓名、生命值和攻击力。
typedef struct {
char name[50];
int health;
int attack_power;
} Character;
// --- 函数声明 ---
void display_stats(const Character* player1, const Character* player2);
void attack(Character* attacker, Character* defender);
int is_game_over(const Character* player1, const Character* player2);
// --- 主函数 ---
int main() {
// 设置随机数种子,确保每次运行的战斗结果不同
srand(time(NULL));
// 创建两个星球大战角色
// `jedi` 代表绝地武士,`sith` 代表西斯尊主
Character jedi = {"Luke Skywalker", MAX_HEALTH, 15};
Character sith = {"Darth Vader", MAX_HEALTH, 18};
printf("欢迎来到光剑对决!\n");
printf("绝地武士 %s vs. 西斯尊主 %s\n\n", jedi.name, sith.name);
// 显示初始状态
display_stats(&jedi, &sith);
// --- 游戏主循环 ---
// 只要双方都还有生命值,战斗就继续
while (!is_game_over(&jedi, &sith)) {
// 绝地武士攻击
attack(&jedi, &sith);
// 如果游戏结束,则跳出循环
if (is_game_over(&jedi, &sith)) break;
// 西斯尊主攻击
attack(&sith, &jedi);
printf("\n");
// 显示当前状态
display_stats(&jedi, &sith);
}
// --- 游戏结束 ---
printf("---------------------------\n");
printf("对决结束!\n");
// 根据最终生命值判断胜者
if (jedi.health > 0) {
printf("%s 赢得了这场光剑对决!愿原力与你同在!\n", jedi.name);
} else {
printf("%s 赢得了这场光剑对决!黑暗面占了上风!\n", sith.name);
}
return 0;
}
// --- 函数实现 ---
/**
* @brief 显示两个角色的当前生命值。
* @param player1 第一个角色的指针。
* @param player2 第二个角色的指针。
*/
void display_stats(const Character* player1, const Character* player2) {
printf("%s 的生命值: %d\n", player1->name, player1->health);
printf("%s 的生命值: %d\n", player2->name, player2->health);
printf("---\n");
}
/**
* @brief 模拟一个角色对另一个角色的攻击。
* @param attacker 攻击者的指针。
* @param defender 防御者的指针。
*/
void attack(Character* attacker, Character* defender) {
// 随机计算本次攻击造成的伤害
int damage = (rand() % (MAX_ATTACK - MIN_ATTACK + 1)) + MIN_ATTACK;
// 绝地武士或西斯尊主用他们的光剑进行攻击
defender->health -= damage;
// 确保生命值不会低于0
if (defender->health < 0) {
defender->health = 0;
}
// 打印战斗日志
printf("%s 用光剑攻击 %s,造成 %d 点伤害!\n", attacker->name, defender->name, damage);
}
/**
* @brief 检查游戏是否结束。
* @param player1 第一个角色的指针。
* @param player2 第二个角色的指针。
* @return 如果任一角色的生命值归零,返回1(游戏结束),否则返回0。
*/
int is_game_over(const Character* player1, const Character* player2) {
// 只要有一方生命值小于等于0,游戏就结束
return player1->health <= 0 || player2->health <= 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> // 用于usleep函数
// 定义终端颜色代码
#define COLOR_YELLOW "\033[1;33m"
#define COLOR_BLUE "\033[1;34m"
#define COLOR_WHITE "\033[1;37m"
#define COLOR_RESET "\033[0m"
// 清屏宏
#define CLEAR_SCREEN() printf("\033[2J\033[H")
// 星战经典开场字幕
const char *starWarsText[] = {
"A long time ago in a galaxy far,",
"far away....",
"",
"STAR WARS",
"",
"Episode IV",
"A NEW HOPE",
"",
"It is a period of civil war.",
"Rebel spaceships, striking",
"from a hidden base, have won",
"their first victory against",
"the evil Galactic Empire.",
"",
"During the battle, Rebel",
"spies managed to steal secret",
"plans to the Empire's",
"ultimate weapon, the DEATH",
"STAR, an armored space",
"station with enough power",
"to destroy an entire planet.",
"",
"Pursued by the Empire's",
"sinister agents, Princess",
"Leia races home aboard her",
"starship, custodian of the",
"stolen plans that can save her",
"people and restore",
"freedom to the galaxy...",
NULL
};
// 函数声明
void printCentered(const char *text, int lineWidth);
void printStarWarsIntro();
void animateText(const char *text, int yPosition, int totalLines);
int main() {
// 隐藏光标(可选)
printf("\033[?25l");
// 打印星战开场
printStarWarsIntro();
// 显示光标
printf("\033[?25h");
return 0;
}
// 打印居中文本
void printCentered(const char *text, int lineWidth) {
int len = strlen(text);
int padding = (lineWidth - len) / 2;
for (int i = 0; i < padding; i++) {
printf(" ");
}
printf("%s", text);
}
// 打印星战开场动画
void printStarWarsIntro() {
int lineWidth = 80; // 假设终端宽度为80字符
int totalLines = 24; // 假设终端高度为24行
int centerY = totalLines / 2;
// 清屏
CLEAR_SCREEN();
// 1. 先显示星战标志(简单模拟)
printf("\n\n\n");
printf("%*s%sSTAR WARS%s\n", (lineWidth - 10) / 2, "", COLOR_YELLOW, COLOR_RESET);
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); // 填充空行
usleep(3000000); // 暂停3秒
// 2. 开始滚动字幕
CLEAR_SCREEN();
// 计算文本行数
int textLines = 0;
while (starWarsText[textLines] != NULL) {
textLines++;
}
// 动画效果:从下往上滚动
for (int i = 0; i < centerY + textLines; i++) {
CLEAR_SCREEN();
// 打印蓝色背景(简单用空格模拟)
for (int j = 0; j < totalLines; j++) {
printf("%*s", lineWidth, "");
}
// 移动到屏幕中心位置开始打印文本
printf("\033[%dA", totalLines); // 向上移动totalLines行
// 打印当前应该显示的文本行
for (int j = 0; j < textLines; j++) {
int currentY = centerY + j - i;
if (currentY >= 0 && currentY < totalLines) {
printf("\033[%dB", currentY); // 移动到当前行
printf("\033[2K"); // 清除当前行
if (j == 3) { // "STAR WARS" 行使用黄色
printf("\033[%dC%s%s%s", (lineWidth - strlen(starWarsText[j])) / 2,
COLOR_YELLOW, starWarsText[j], COLOR_RESET);
} else if (j == 6) { // "A NEW HOPE" 行使用蓝色
printf("\033[%dC%s%s%s", (lineWidth - strlen(starWarsText[j])) / 2,
COLOR_BLUE, starWarsText[j], COLOR_RESET);
} else {
printf("\033[%dC%s%s%s", (lineWidth - strlen(starWarsText[j])) / 2,
COLOR_WHITE, starWarsText[j], COLOR_RESET);
}
printf("\033[%dA", currentY); // 移回顶部
}
}
fflush(stdout); // 确保立即输出
usleep(200000); // 暂停200毫秒
}
// 动画结束,保持最后状态
usleep(5000000); // 暂停5秒
}
<?php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
function fetchAPI($url, $timeout = 10) {
$start = microtime(true);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Origin: https://example.com']);
$response = curl_exec($ch);
$err = curl_errno($ch);
$latency = round((microtime(true) - $start) * 1000);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($err || $httpCode >= 400 || $response === false) {
return ['success'=>false, 'latency'=>$latency];
}
return ['success'=>true, 'latency'=>$latency, 'body'=>$response];
}
function parseIPInfo($api, $response) {
$result = ['ip'=>'未知','location'=>'未知','isp'=>'未知'];
if (!$response['success']) return $result;
$body = $response['body'];
switch ($api) {
case 'myip.ipip.net':
if (preg_match('/当前 IP:([\d.:]+)\s+来自于:(.+)/u', $body, $m)) {
$result['ip'] = $m[1];
$result['location'] = $m[2];
$result['isp'] = $m[2];
}
break;
case 'ipapi.co':
case 'ipwhois.app':
case 'ip-api.com':
case 'ipinfo.io':
case 'ipdata.co':
case 'icanhazip.com':
case 'checkip.amazonaws.com':
$data = json_decode($body,true);
if ($data) {
if(isset($data['ip'])) $result['ip'] = $data['ip'];
elseif(isset($data['query'])) $result['ip'] = $data['query'];
if(isset($data['country'],$data['regionName'],$data['city'])) {
$result['location'] = $data['country'].' '.$data['regionName'].' '.$data['city'];
} elseif(isset($data['country'],$data['region'],$data['city'])) {
$result['location'] = $data['country'].' '.$data['region'].' '.$data['city'];
} elseif(isset($data['country'])) {
$result['location'] = $data['country'];
}
if(isset($data['isp'])) $result['isp'] = $data['isp'];
elseif(isset($data['org'])) $result['isp'] = $data['org'];
}
break;
case 'surfshark':
case 'ipify':
$data = json_decode($body,true);
if ($data) {
if(isset($data['ip'])) $result['ip'] = $data['ip'];
if(isset($data['isp'])) $result['isp'] = $data['isp'];
if(isset($data['country'],$data['region'],$data['city'])) {
$result['location'] = $data['country'].' '.$data['region'].' '.$data['city'];
} elseif(isset($data['country'])) {
$result['location'] = $data['country'];
}
}
break;
}
return $result;
}
// 配置 API 列表
$domesticAPIs = ['myip.ipip.net'];
$internationalAPIs = [
'ipapi.co/json/', 'https://ipv4.icanhazip.com', 'https://checkip.amazonaws.com',
'https://ipwhois.app/json/', 'http://ip-api.com/json', 'https://ipinfo.io/json',
'https://api.ipdata.co'
];
$blockedAPIs = ['https://api.surfshark.com/v1/server/user', 'https://api.ipify.org?format=json'];
$output = ['domestic'=>[],'international'=>[],'blocked'=>[]];
// 国内出口 IP
foreach($domesticAPIs as $api){
$res = fetchAPI("https://$api");
$info = parseIPInfo('myip.ipip.net', $res);
$info['latency'] = $res['latency'];
$info['success'] = $res['success'];
$output['domestic'][] = ['api'=>$api]+$info;
}
// 国外出口 IP
foreach($internationalAPIs as $api){
$res = fetchAPI($api);
$key = str_replace(['https://','http://','/json/'],'',$api);
$info = parseIPInfo($key, $res);
$info['latency'] = $res['latency'];
$info['success'] = $res['success'];
$output['international'][] = ['api'=>$api]+$info;
}
// 被墙线路 IP
foreach($blockedAPIs as $api){
$res = fetchAPI($api);
$key = strpos($api,'surfshark')!==false?'surfshark':'ipify';
$info = parseIPInfo($key, $res);
$info['latency'] = $res['latency'];
$info['success'] = $res['success'];
$output['blocked'][] = ['api'=>$api]+$info;
}
echo json_encode($output, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
<!-- 访问信息 -->
<style>
#visit-ip-container {
font-size: 1.4rem;
font-weight: 500;
color: #000000;
background: linear-gradient(135deg, #d4f0f0, #e9f8fa);
padding: 20px;
border-radius: 16px;
box-shadow: 0 4px 20px rgba(1, 127, 145, 0.3);
backdrop-filter: blur(12px);
position: relative;
overflow: hidden;
margin: 15px 0;
}
#visit-ip-container::before {
content: "";
position: absolute;
top: -40%;
left: -50%;
width: 200%;
height: 180%;
background: linear-gradient(120deg, transparent 30%, rgba(1,127,145,0.15) 50%, transparent 70%);
animation: shimmer 1s linear infinite !important;
pointer-events: none;
border-radius: 16px;
z-index: 0;
}
.ip-section {
position: relative;
z-index: 1;
margin: 12px 0;
padding: 10px 15px;
background: rgba(255, 255, 255, 0.6);
border-radius: 10px;
border-left: 4px solid #017f91;
animation: fadeInSlide 0.8s ease-out forwards;
opacity: 0;
transform: translateY(20px);
}
.ip-section:nth-child(1){animation-delay:0.1s}
.ip-section:nth-child(2){animation-delay:0.3s}
.ip-section:nth-child(3){animation-delay:0.5s}
.ip-label{font-weight:600;color:#017f91;margin-bottom:5px;}
.ip-info{font-size:1.2rem;line-height:1.4;word-break:break-all;}
.ip-loading{color:#666;font-style:italic;}
.ip-error{color:#d32f2f;}
.ip-success{color:#2e7d32;}
.visit-counter-section{text-align:center;margin-bottom:15px;padding:10px;background: rgba(255,255,255,0.7);border-radius:10px;font-weight:600;font-size:1.6rem;color:#017f91;}
@keyframes shimmer {0%{transform:translateX(-100%) translateY(0);}100%{transform:translateX(100%) translateY(0);}}
@keyframes fadeInSlide {to{opacity:1;transform:translateY(0);}}
@keyframes pulse {0%,100%{transform:scale(1);}50%{transform:scale(1.02);}}
.loading-animation{animation:pulse 1.5s ease-in-out infinite;}
</style>
<div id="visit-ip-container">
<div class="visit-counter-section">
<div id="visit-counter">访问次数:小二正在努力加载,请你稍等...</div>
</div>
<div class="ip-section loading-animation">
<div class="ip-label">国内出口 IP</div>
<div id="domestic-ip" class="ip-info ip-loading">正在检测国内线路...</div>
</div>
<div class="ip-section loading-animation">
<div class="ip-label">国外出口 IP</div>
<div id="international-ip" class="ip-info ip-loading">正在检测国际线路...</div>
</div>
<div class="ip-section loading-animation">
<div class="ip-label">被墙线路 IP</div>
<div id="blocked-ip" class="ip-info ip-loading">正在检测受限线路...</div>
</div>
</div>
<script>
;(async function(){
// 访问次数
let cnt = localStorage.getItem('visit_count') || 0;
cnt++;
localStorage.setItem('visit_count', cnt);
document.getElementById('visit-counter').textContent = '访问次数:' + cnt;
// helper: 清除 loading 动画
function clearLoading(id) {
const sec = document.getElementById(id).closest('.ip-section');
sec && sec.classList.remove('loading-animation');
}
// helper: 渲染某个 section
function renderSection(id, list){
const container = document.getElementById(id);
if(!Array.isArray(list) || list.length === 0){
container.innerHTML = '<span class="ip-error">未获得数据</span>';
clearLoading(id);
return;
}
// 构造 <ul>
const items = list.map(it=>{
if(it.success){
return `<li>
<strong>${it.api}</strong><br>
IP: <span class="ip-success">${it.ip}</span><br>
归属地: ${it.location||'未知'}<br>
ISP: ${it.isp||'未知'}<br>
延迟: ${it.latency} ms
</li>`;
} else {
return `<li><strong>${it.api}</strong>: <span class="ip-error">连接失败</span> (延迟 ${it.latency} ms)</li>`;
}
}).join('');
container.innerHTML = `<ul style="padding-left:20px; margin:0;">${items}</ul>`;
clearLoading(id);
}
try {
const resp = await fetch('/ip.php');
const data = await resp.json();
renderSection('domestic-ip', data.domestic);
renderSection('international-ip', data.international);
renderSection('blocked-ip', data.blocked);
} catch(err) {
console.error('前端获取 /ip.php 失败', err);
['domestic-ip','international-ip','blocked-ip'].forEach(id=>{
document.getElementById(id).innerHTML = '<span class="ip-error">请求错误</span>';
clearLoading(id);
});
}
})();
</script>